Crow icon indicating copy to clipboard operation
Crow copied to clipboard

Chain calling creates errors when loading `rvalue` to `vector`

Open dphung2000 opened this issue 3 years ago • 3 comments

Consider the code below:

#include "crow.h"
#include <string>
#include <iostream>
#include <vector>

using string = std::string;
using rvalue = crow::json::rvalue;
using wvalue = crow::json::wvalue;
int main(){
    for (int i = 0; i < 2; i++) {
        //long string
        string x = "[{\"clock\":\"1648149153\",\"itemid\":\"39933\",\"ns\":\"347391001\",\"value\":\"975099\"},{\"clock\":\"1648149152\",\"itemid\":\"39932\",\"ns\":\"346766425\",\"value\":\"13742150069\"},{\"clock\":\"1648149093\",\"itemid\":\"39933\",\"ns\":\"322533930\",\"value\":\"975039\"},{\"clock\":\"1648149092\",\"itemid\":\"39932\",\"ns\":\"322115110\",\"value\":\"13740459337\"},{\"clock\":\"1648149033\",\"itemid\":\"39933\",\"ns\":\"296445219\",\"value\":\"974979\"},{\"clock\":\"1648149032\",\"itemid\":\"39932\",\"ns\":\"295743229\",\"value\":\"13738772190\"},{\"clock\":\"1648148973\",\"itemid\":\"39933\",\"ns\":\"267044669\",\"value\":\"974919\"},{\"clock\":\"1648148972\",\"itemid\":\"39932\",\"ns\":\"264670079\",\"value\":\"13737076183\"},{\"clock\":\"1648148913\",\"itemid\":\"39933\",\"ns\":\"241073210\",\"value\":\"974859\"},{\"clock\":\"1648148912\",\"itemid\":\"39932\",\"ns\":\"236625949\",\"value\":\"13735384683\"}]";
        //short string
        //x = "[{\"clock\":\"1648149153\",\"itemid\":\"39933\",\"ns\":\"347391001\",\"value\":\"975099\"}]";
        std::vector<rvalue> fetch = crow::json::load(x).lo();
        for (auto x: fetch) std::cout << x;       
    }
}

Compiled using:

g++ -std=c++14 -Wall -I ~/Crow/include -I ~/boost_1_77_0 check.cpp -o bruh -lpthread

I ran this code and it resulted in "segmentation fault", nothing else was printed to my console. The short string worked, however. When I changed my method chains to separate commands:

std::vector<rvalue> fetch = crow::json::load(x).lo();

to

rvalue new_x = crow::json::load(x);
std::vector<rvalue> fetch = new_x.lo();

It worked for both short string and long string. Is this a fault specific to your library or is it due to C++ itself? Thank you in advance.

dphung2000 avatar Mar 24 '22 20:03 dphung2000

Well this is definitely strange, for me I'm not getting a segfault error but "clock":"1648149153" is getting replaced with "U\u0005\u0000\u0000\u0000":"u�:49153". this is compiled using g++ (GCC) 11.2.0 and boost 1.78.0.

Which version of GCC are you using?

This might be because crow::json primarily uses c strings rather than C++ strings, which could lead to this unexpected behavior.

The separated calls are working normally by the way.

The-EDev avatar Mar 25 '22 12:03 The-EDev

I also get your weird literal unicode string in my production code as well. But I couldn't replicate the error with the sample code. My gcc version is also 11.2.0.

dphung2000 avatar Mar 25 '22 14:03 dphung2000

The issue seems to occur whenever the rvalue is destructed before the for loop is run. for example if the 2 lines are wrapped with {}, the same issue occurs. This is because in both cases, the result of crow::json::load is discarded before the for loop is run. Which might indicate that some data that would be moved or copied remain under the ownership of the rvalue that would later be deleted.

I'll need to look into how .lo() works and figure out what the issue is.

The-EDev avatar Jun 30 '22 03:06 The-EDev