Json-Glib 对象插入时跳转无效
Json-Glib Invalid jumps on object insertions
我正在使用 C 语言 Json 库,即 Json-Glib。
问题是图书馆一直在对我进行段错误,我不明白为什么。我阅读了所有文档,了解到根节点可以包含一些原始值,但更重要的是一个对象。我正在尝试实现一个对象串联,但是当我尝试将一个对象放入一个节点中,或者甚至只是在其中添加字符串成员时,我得到无效跳转作为通常大小 8(string) 的无效读取。
这是试图从 Json 节点检索 Json 对象的代码,因为在检索到的 Json 对象中插入少量字符串。
int main(){
const gchar *auth = "authentication";
//here i initialize my Root JsonNode with an object in it and a JsonObject to be able to get the object from the JsonNode
JsonObject* authObject = json_object_new();
JsonNode* extNode = json_node_new(JSON_NODE_OBJECT);
// Here i retrieve the initialized JsonObject that is inside my JsonNode
authObject = json_node_get_object(extNode);
// And here some few insertion of strings in the object
SegFault Here -> json_object_set_string_member(authObject, "action", "authenticate");
json_object_set_string_member(authObject, "type", "authType");
json_object_set_string_member(authObject, "resource", "resource");
json_object_set_string_member(authObject, "version", "none");
json_object_set_string_member(authObject, "data", "loginData");
//here i try to print my json file but i can't even reach this execution line due to SegFault
char* toto = cometd_json_node2str(extNode);
puts(toto);
return 0;
}
这是 Valgrind 报告:
==4910== Memcheck, a memory error detector
==4910== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4910== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==4910== Command: ./a.out
==4910==
==4910== Invalid read of size 8
==4910== at 0x10013C28D: json_object_set_string_member (in /usr/local/Cellar/json-glib/1.0.2/lib/libjson-glib-1.0.0.dylib)
==4910== by 0x100000DD1: main (main.c:50)
==4910== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==4910==
==4910==
==4910== Process terminating with default action of signal 11 (SIGSEGV)
==4910== Access not within mapped region at address 0x0
==4910== at 0x10013C28D: json_object_set_string_member (in /usr/local/Cellar/json-glib/1.0.2/lib/libjson-glib-1.0.0.dylib)
==4910== by 0x100000DD1: main (main.c:50)
==4910== If you believe this happened as a result of a stack
==4910== overflow in your program's main thread (unlikely but
==4910== possible), you can try to increase the size of the
==4910== main thread stack using the --main-stacksize= flag.
==4910== The main thread stack size used in this run was 8388608.
==4910==
==4910== HEAP SUMMARY:
==4910== in use at exit: 836,054 bytes in 2,098 blocks
==4910== total heap usage: 2,577 allocs, 479 frees, 1,410,814 bytes allocated
==4910==
==4910== LEAK SUMMARY:
==4910== definitely lost: 3,167 bytes in 45 blocks
==4910== indirectly lost: 5,357 bytes in 22 blocks
==4910== possibly lost: 20,836 bytes in 214 blocks
==4910== still reachable: 128,596 bytes in 853 blocks
==4910== suppressed: 678,098 bytes in 964 blocks
==4910== Rerun with --leak-check=full to see details of leaked memory
==4910==
==4910== For counts of detected and suppressed errors, rerun with: -v
==4910== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 1 from 1)
任何帮助将不胜感激,事实上,如果我可以调试它,我会写一篇关于 Json-Glib 的教程,以帮助其他程序员不为它苦苦挣扎。
您正在覆盖 authObject
指针:
JsonObject* authObject = json_object_new(); // ← You create it here…
JsonNode* extNode = json_node_new(JSON_NODE_OBJECT);
authObject = json_node_get_object(extNode); // ← … but overwrite it here
在新创建的 JsonNode
上调用 json_node_get_object()
将 return NULL
,因为您尚未设置对象。
如果你想用对象设置 JsonNode
,请改用 json_node_init_object()
:
JsonObject *authObject = json_object_new ();
JsonNode *node = json_node_init_object (json_node_alloc (), authObject);
或使用json_node_new()
和json_node_take_object()
:
JsonObject *authObject = json_object_new ();
JsonNode *node = json_node_new (JSON_NODE_OBJECT);
json_node_take_object (node, authObject);
现在您可以添加成员到 authObject
。
以下是我如何应用 ebassi 先生的回答。更一般地说,我是如何让它发挥作用的。
cometd_new_handshake_message(const cometd* h)
{
gint64 seed = ++(h->conn->msg_id_seed);
/////////////////Data Concatenation/////////////
JsonObject* dataObject = json_object_new();
JsonNode* dataNode = json_node_new(JSON_NODE_OBJECT); JsonNode* dataRoot = json_node_init_object(dataNode, dataObject);
dataObject = json_node_get_object(dataRoot);
json_object_set_string_member(dataObject, "login", "test2");
json_object_set_string_member(dataObject, "password", "password");
////////////////Data Concatenation////////////
/////////////////Auth/////////////////
// I begin from the most inner JsonObject of my Json File
//here i initialize my Root JsonNode with an object in it and a JsonObject to be able to get the object from the JsonNode
JsonObject* authObject = json_object_new();
JsonNode* authNode = json_node_new(JSON_NODE_OBJECT);
JsonNode* authRoot = json_node_init_object(authNode, authObject);
// Here i retrieve the initialized JsonObject that is inside my JsonNode
authObject = json_node_get_object(authRoot);
// And here some few insertion of strings in the object
json_object_set_string_member(authObject, "action", "authenticate");
json_object_set_string_member(authObject, "type", "GmY-HuzW.KZyH.simple");
json_object_set_string_member(authObject, "resource", "zetapushTuto");
json_object_set_member(authObject, "data", dataRoot);
///////////////Auth/////////////////
//////////////First Concatenation : Authentication///////////////
//Here i make the authentication of my first JsonObject with a upper membrane.
JsonObject *extMembrane = json_object_new();
JsonNode *contactMembrane = json_node_new(JSON_NODE_OBJECT); JsonNode *secondRootMembrane = json_node_init_object(contactMembrane, extMembrane);
extMembrane = json_node_get_object(secondRootMembrane);
json_object_set_member(extMembrane, "authentication", authRoot);
/////////////First Concatenation////////////////
////////////Second Concatenation : Ext///////////////
// Here i finnaly concatenante my last JsonObject and encapsulate the overall file inside the root JsonNode
JsonObject *rootObjectMembrane = json_object_new();
JsonNode *initRootMembrane = json_node_new(JSON_NODE_OBJECT);
JsonNode *rootMembrane = json_node_init_object(initRootMembrane, rootObjectMembrane);
rootObjectMembrane = json_node_get_object(rootMembrane);
json_object_set_member(rootObjectMembrane, "ext", secondRootMembrane);
// I still needs to create a object under Ext JsonNode, then an JsonArray to supportedConnectionTypes
//Then add the advice object with "timeout" and "interval"
json_object_set_int_member(rootObjectMembrane, "id", seed);
json_object_set_string_member(rootObjectMembrane, "version", "1.0");
json_object_set_string_member(rootObjectMembrane, "minimumVersion", "1.0");
json_object_set_string_member(rootObjectMembrane, "channel", "/meta/handshake");
JsonArray* json_transports = json_array_new();
GList* entry = h->config->transports;
while (entry){
cometd_transport* t = entry->data;
json_array_add_string_element(json_transports, t->name);
entry = g_list_next(entry);
}
//json_array_add_string_element(json_transports, "long-polling");
json_object_set_array_member(rootObjectMembrane, "supportedConnectionTypes", json_transports);
//////////Advice////////
JsonObject *adviceMembrane = json_object_new();
JsonNode *adviceNodeMembrane = json_node_new(JSON_NODE_OBJECT);
JsonNode *adviceRootMembrane = json_node_init_object(adviceNodeMembrane, adviceMembrane);
gint64 interval = 0;
gint64 timeout = 60000;
adviceMembrane = json_node_get_object(adviceRootMembrane);
json_object_set_int_member(adviceMembrane, "timeout", timeout);
json_object_set_int_member(adviceMembrane, "interval", interval);
json_object_set_member(rootObjectMembrane, "advice", adviceRootMembrane);
/////////Advice////////
////////////Second Concatenation//////////////
// call extensions with message - TODO: implement extensions first
//json_node_take_object(root, obj);
return rootMembrane;
}
我正在使用 C 语言 Json 库,即 Json-Glib。 问题是图书馆一直在对我进行段错误,我不明白为什么。我阅读了所有文档,了解到根节点可以包含一些原始值,但更重要的是一个对象。我正在尝试实现一个对象串联,但是当我尝试将一个对象放入一个节点中,或者甚至只是在其中添加字符串成员时,我得到无效跳转作为通常大小 8(string) 的无效读取。 这是试图从 Json 节点检索 Json 对象的代码,因为在检索到的 Json 对象中插入少量字符串。
int main(){
const gchar *auth = "authentication";
//here i initialize my Root JsonNode with an object in it and a JsonObject to be able to get the object from the JsonNode
JsonObject* authObject = json_object_new();
JsonNode* extNode = json_node_new(JSON_NODE_OBJECT);
// Here i retrieve the initialized JsonObject that is inside my JsonNode
authObject = json_node_get_object(extNode);
// And here some few insertion of strings in the object
SegFault Here -> json_object_set_string_member(authObject, "action", "authenticate");
json_object_set_string_member(authObject, "type", "authType");
json_object_set_string_member(authObject, "resource", "resource");
json_object_set_string_member(authObject, "version", "none");
json_object_set_string_member(authObject, "data", "loginData");
//here i try to print my json file but i can't even reach this execution line due to SegFault
char* toto = cometd_json_node2str(extNode);
puts(toto);
return 0;
}
这是 Valgrind 报告:
==4910== Memcheck, a memory error detector
==4910== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4910== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==4910== Command: ./a.out
==4910==
==4910== Invalid read of size 8
==4910== at 0x10013C28D: json_object_set_string_member (in /usr/local/Cellar/json-glib/1.0.2/lib/libjson-glib-1.0.0.dylib)
==4910== by 0x100000DD1: main (main.c:50)
==4910== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==4910==
==4910==
==4910== Process terminating with default action of signal 11 (SIGSEGV)
==4910== Access not within mapped region at address 0x0
==4910== at 0x10013C28D: json_object_set_string_member (in /usr/local/Cellar/json-glib/1.0.2/lib/libjson-glib-1.0.0.dylib)
==4910== by 0x100000DD1: main (main.c:50)
==4910== If you believe this happened as a result of a stack
==4910== overflow in your program's main thread (unlikely but
==4910== possible), you can try to increase the size of the
==4910== main thread stack using the --main-stacksize= flag.
==4910== The main thread stack size used in this run was 8388608.
==4910==
==4910== HEAP SUMMARY:
==4910== in use at exit: 836,054 bytes in 2,098 blocks
==4910== total heap usage: 2,577 allocs, 479 frees, 1,410,814 bytes allocated
==4910==
==4910== LEAK SUMMARY:
==4910== definitely lost: 3,167 bytes in 45 blocks
==4910== indirectly lost: 5,357 bytes in 22 blocks
==4910== possibly lost: 20,836 bytes in 214 blocks
==4910== still reachable: 128,596 bytes in 853 blocks
==4910== suppressed: 678,098 bytes in 964 blocks
==4910== Rerun with --leak-check=full to see details of leaked memory
==4910==
==4910== For counts of detected and suppressed errors, rerun with: -v
==4910== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 1 from 1)
任何帮助将不胜感激,事实上,如果我可以调试它,我会写一篇关于 Json-Glib 的教程,以帮助其他程序员不为它苦苦挣扎。
您正在覆盖 authObject
指针:
JsonObject* authObject = json_object_new(); // ← You create it here…
JsonNode* extNode = json_node_new(JSON_NODE_OBJECT);
authObject = json_node_get_object(extNode); // ← … but overwrite it here
在新创建的 JsonNode
上调用 json_node_get_object()
将 return NULL
,因为您尚未设置对象。
如果你想用对象设置 JsonNode
,请改用 json_node_init_object()
:
JsonObject *authObject = json_object_new ();
JsonNode *node = json_node_init_object (json_node_alloc (), authObject);
或使用json_node_new()
和json_node_take_object()
:
JsonObject *authObject = json_object_new ();
JsonNode *node = json_node_new (JSON_NODE_OBJECT);
json_node_take_object (node, authObject);
现在您可以添加成员到 authObject
。
以下是我如何应用 ebassi 先生的回答。更一般地说,我是如何让它发挥作用的。
cometd_new_handshake_message(const cometd* h)
{
gint64 seed = ++(h->conn->msg_id_seed);
/////////////////Data Concatenation/////////////
JsonObject* dataObject = json_object_new();
JsonNode* dataNode = json_node_new(JSON_NODE_OBJECT); JsonNode* dataRoot = json_node_init_object(dataNode, dataObject);
dataObject = json_node_get_object(dataRoot);
json_object_set_string_member(dataObject, "login", "test2");
json_object_set_string_member(dataObject, "password", "password");
////////////////Data Concatenation////////////
/////////////////Auth/////////////////
// I begin from the most inner JsonObject of my Json File
//here i initialize my Root JsonNode with an object in it and a JsonObject to be able to get the object from the JsonNode
JsonObject* authObject = json_object_new();
JsonNode* authNode = json_node_new(JSON_NODE_OBJECT);
JsonNode* authRoot = json_node_init_object(authNode, authObject);
// Here i retrieve the initialized JsonObject that is inside my JsonNode
authObject = json_node_get_object(authRoot);
// And here some few insertion of strings in the object
json_object_set_string_member(authObject, "action", "authenticate");
json_object_set_string_member(authObject, "type", "GmY-HuzW.KZyH.simple");
json_object_set_string_member(authObject, "resource", "zetapushTuto");
json_object_set_member(authObject, "data", dataRoot);
///////////////Auth/////////////////
//////////////First Concatenation : Authentication///////////////
//Here i make the authentication of my first JsonObject with a upper membrane.
JsonObject *extMembrane = json_object_new();
JsonNode *contactMembrane = json_node_new(JSON_NODE_OBJECT); JsonNode *secondRootMembrane = json_node_init_object(contactMembrane, extMembrane);
extMembrane = json_node_get_object(secondRootMembrane);
json_object_set_member(extMembrane, "authentication", authRoot);
/////////////First Concatenation////////////////
////////////Second Concatenation : Ext///////////////
// Here i finnaly concatenante my last JsonObject and encapsulate the overall file inside the root JsonNode
JsonObject *rootObjectMembrane = json_object_new();
JsonNode *initRootMembrane = json_node_new(JSON_NODE_OBJECT);
JsonNode *rootMembrane = json_node_init_object(initRootMembrane, rootObjectMembrane);
rootObjectMembrane = json_node_get_object(rootMembrane);
json_object_set_member(rootObjectMembrane, "ext", secondRootMembrane);
// I still needs to create a object under Ext JsonNode, then an JsonArray to supportedConnectionTypes
//Then add the advice object with "timeout" and "interval"
json_object_set_int_member(rootObjectMembrane, "id", seed);
json_object_set_string_member(rootObjectMembrane, "version", "1.0");
json_object_set_string_member(rootObjectMembrane, "minimumVersion", "1.0");
json_object_set_string_member(rootObjectMembrane, "channel", "/meta/handshake");
JsonArray* json_transports = json_array_new();
GList* entry = h->config->transports;
while (entry){
cometd_transport* t = entry->data;
json_array_add_string_element(json_transports, t->name);
entry = g_list_next(entry);
}
//json_array_add_string_element(json_transports, "long-polling");
json_object_set_array_member(rootObjectMembrane, "supportedConnectionTypes", json_transports);
//////////Advice////////
JsonObject *adviceMembrane = json_object_new();
JsonNode *adviceNodeMembrane = json_node_new(JSON_NODE_OBJECT);
JsonNode *adviceRootMembrane = json_node_init_object(adviceNodeMembrane, adviceMembrane);
gint64 interval = 0;
gint64 timeout = 60000;
adviceMembrane = json_node_get_object(adviceRootMembrane);
json_object_set_int_member(adviceMembrane, "timeout", timeout);
json_object_set_int_member(adviceMembrane, "interval", interval);
json_object_set_member(rootObjectMembrane, "advice", adviceRootMembrane);
/////////Advice////////
////////////Second Concatenation//////////////
// call extensions with message - TODO: implement extensions first
//json_node_take_object(root, obj);
return rootMembrane;
}