我正在尝试创建一个名为StatusItem
的结构数组,如下所示:
typedef struct
{
char* name;
char* index;
int optional;
} StatusItem;
此外,由于我希望此数组具有任何大小,我使用的是malloc
。所以数组定义如下:
StatusItem* statusItem = NULL;
(然后传递给函数,该函数检索所有值,如下所示。)
statusItem = (StatusItem*)malloc(cJSON_GetArraySize(items));
...
for (i = 0 ; i < cJSON_GetArraySize(items) ; i++)
{
strcpy(statusItem[i].name,name->valuestring);
strcpy(statusItem[i].index,index->valuestring);
if(!parseInt(optional->valuestring, &statusItem[i].optional));
{
goto cleanup;
}
}
有代码涉及cJSON库,将name
,index
和optional
的字符串值放入上面引用的变量中,并将它们存储在{{1}中这些变量的字段。
我已经检查过涉及cJSON库的所有内容都正常工作,并返回正确的值,但程序无法访问或存储valuestring
数组中的值。
有什么想法吗?我几乎是肯定的,这涉及我statusItems
的一些误用。
答案 0 :(得分:4)
1)cJSON_GetArraySize(items)
返回元素数 - 您需要考虑因素的大小:malloc(cJSON_GetArraySize(items) * sizeof(StatusItem))
2)StatusItem
结构没有实际字符串的内存 - 只有指向字符串的指针。您可以使用strdup()
分配和复制字符串。
您可能希望代码看起来更像:
statusItem = (StatusItem*)malloc(cJSON_GetArraySize(items) * sizeof(StatusItem));
...
for (i = 0 ; i < cJSON_GetArraySize(items) ; i++)
{
statusItem[i].name = strdup(name->valuestring);
statusItem[i].index = strdup(index->valuestring);
if(!parseInt(optional->valuestring, &statusItem[i].optional));
{
goto cleanup;
}
}
当然,这意味着当您释放StatusItem
个对象数组时,您还必须显式释放重复的字符串:
// to free the statusItem array, and the various strings it refers to:
for (i = 0 ; i < cJSON_GetArraySize(items) ; i++)
{
free(statusItem[i].name);
free(statusItem[i].index);
}
free(statusItem);
答案 1 :(得分:2)
发现了两个误用:
Don't cast the return value of malloc()
, it's dangerous and superfluous.
您没有为结构成员分配任何内存 - 您strcpy()
指向未初始化的指针,因此您的程序会调用未定义的行为。
编辑:实际上是三个:
malloc(cJSON_GetArraySize(items));
没有分配足够的内存,因为它不是魔术并且它不知道你正在保留sizeof(StatusItem)
字节的内存,因此你必须将分配大小乘以sizeof(StatusItem)
,甚至更好,sizeof(*statusItem)
为安全起见。
答案 2 :(得分:0)
此外,malloc需要多个字节,而不是元素。传递给它的值必须乘以每个元素的大小。
答案 3 :(得分:0)
为了避免使用strdup()
这有点'杂乱',因为它让内存释放到调用者而不是自己处理所有事情,我修改了我现有的结构如下:
typedef struct
{
char name[32];
char index[32];
int optional;
} StatusItem;
这允许32个字节用于名称和索引,这应该足够了。之前,结构字段指向任何内容,这在尝试复制到该位置时导致错误。现在,有空(或垃圾)内存等待放入字符串。
这允许仍然使用strcpy()
,并允许整体更清洁。