为什么我的程序在不同函数中第二次使用字符串后崩溃?
Why my program crashes after second usage of a string in different functions?
当我 运行 我的程序时,它调用一个具有 "char *msgtype" 的函数并且该函数可能工作但是当程序到达时另一个函数在其中使用不同的 "char *msgtype"包含它的行,程序崩溃(甚至当第一个函数被调用第二次程序崩溃时)。有什么问题?
如果我在第二个函数中更改名称,它只会工作一次,而在再次调用该函数后程序会崩溃!
void fun1(){
...
cJSON *root = cJSON_Parse(buffer);
char *msgtype = cJSON_GetObjectItem(root,"type")->valuestring;
...
free(msgtype);
cJSON_Delete(root);
...
}
void fun2(){
...
cJSON *root = cJSON_Parse(buffer);
char *msgtype = cJSON_GetObjectItem(root,"type")->valuestring;//it crashes here
...
free(msgtype);
cJSON_Delete(root);
...
}
int main(){
fun1();
fun2();//it crashes inside this function !
}
你知道 cJSON_GetObjectItem()
return 是什么吗?它是指向数据结构的指针,还是数据的副本?如果它 return 是指向更大结构的一部分的指针,则不应使用 free()
释放它——当您销毁 cjSON
对象时它会被释放。
如果您看一下 get_object_item()
的代码 — 它直接从 cJSON.c
中的 cJSON_GetObjectItem()
调用,您会看到它 return 是指向cJSON
对象的中间。您负担不起调用 free()
那个 return 值。您应该只对完整的对象调用 cJSON_Delete()
。通过调用 free(msgtype)
,您正在破坏 root
数据结构的完整性 — 并且您最终可能也会遇到双重释放问题。
如果它适用于您的平台,请使用 Valgrind 分析问题所在 - 它可能会告诉您。如果您系统的 malloc()
实现有调试挂钩(例如 macOS 上的版本有),请考虑使用它们。
当我 运行 我的程序时,它调用一个具有 "char *msgtype" 的函数并且该函数可能工作但是当程序到达时另一个函数在其中使用不同的 "char *msgtype"包含它的行,程序崩溃(甚至当第一个函数被调用第二次程序崩溃时)。有什么问题?
如果我在第二个函数中更改名称,它只会工作一次,而在再次调用该函数后程序会崩溃!
void fun1(){
...
cJSON *root = cJSON_Parse(buffer);
char *msgtype = cJSON_GetObjectItem(root,"type")->valuestring;
...
free(msgtype);
cJSON_Delete(root);
...
}
void fun2(){
...
cJSON *root = cJSON_Parse(buffer);
char *msgtype = cJSON_GetObjectItem(root,"type")->valuestring;//it crashes here
...
free(msgtype);
cJSON_Delete(root);
...
}
int main(){
fun1();
fun2();//it crashes inside this function !
}
你知道 cJSON_GetObjectItem()
return 是什么吗?它是指向数据结构的指针,还是数据的副本?如果它 return 是指向更大结构的一部分的指针,则不应使用 free()
释放它——当您销毁 cjSON
对象时它会被释放。
如果您看一下 get_object_item()
的代码 — 它直接从 cJSON.c
中的 cJSON_GetObjectItem()
调用,您会看到它 return 是指向cJSON
对象的中间。您负担不起调用 free()
那个 return 值。您应该只对完整的对象调用 cJSON_Delete()
。通过调用 free(msgtype)
,您正在破坏 root
数据结构的完整性 — 并且您最终可能也会遇到双重释放问题。
如果它适用于您的平台,请使用 Valgrind 分析问题所在 - 它可能会告诉您。如果您系统的 malloc()
实现有调试挂钩(例如 macOS 上的版本有),请考虑使用它们。