动态字符串列表和 free() 崩溃应用程序
Dynamic string list and free() crashing application
我写了一个简单的 C 代码,它应该在一个结构中存储一个字符串地址列表 (char*)。该列表是动态的,所以每次添加一个新字符串时,我都会预留足够的内存来存储所有当前字符串地址加上新地址。然后我释放旧缓冲区并将新缓冲区分配给结构。问题是它在 free() 上崩溃。
我确信我有空()ing我从calloc()得到的确切地址,但它仍然崩溃了。
这是输出:
main(3618,0x7fff7a83f300) malloc: *** error for object 0x7f9902404bd0: incorrect checksum for freed object - object was probably modified after being freed.
密码是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct StructNODE{
char** stringlist;
int stringcount;
struct StructNODE* next;
} NODE;
void Addstring(NODE* node, const char* string)
{
int currentBufferSize = node->stringcount * sizeof(char*);
// make room for the current string list plus the new one
char** addrList = (char**) calloc( 1, currentBufferSize );
printf("malloc: %d bytes starting at 0x%X\n",currentBufferSize, addrList);
// copy all current addresses to the new list
memcpy(addrList, node->stringlist, currentBufferSize);
printf("freeing mem at 0x%X\n",node->stringlist);
free(node->stringlist);
// Append the new address to the end of the address buffer
addrList[node->stringcount] = (char*)string;
//make the node point to the new buffer
node->stringlist = addrList;
// Increment the string number counter
node->stringcount++;
}
void PrintStringlist(NODE* node)
{
int i;
for ( i=0; i < node->stringcount; i++)
{
printf("string %d: %s\n",i, node->stringlist[i]);
}
}
int main(int argc, char** argv)
{
NODE* node = (NODE*) calloc(1 , sizeof(NODE));
Addstring(node, "Lewis Skolnick");
Addstring(node, "Gilbert Lowe");
Addstring(node, "Arnold Poindexter");
Addstring(node, "Harold Wormser");
Addstring(node, "Booger");
Addstring(node, "Takashi Toshiro");
Addstring(node, "Lamar Latrelle");
Addstring(node, "Judy");
PrintStringlist(node);
return 0;
}
我忽略了什么?
您的缓冲区太小 - 您忘记为额外元素添加 space。第一个函数行应该是:
int currentBufferSize = (node->stringcount + 1) * sizeof(char*);
calloc
的签名如下:
void* calloc (size_t num, size_t size);
因此,假设 stringcount
是实际金额,您应该使用不同的参数调用它,例如
calloc(sizeof(char*), node->stringcount +1)
无论如何,stdlib 中还有另一个有用的函数 realloc
,它允许您直接调整分配的内存大小,而无需自己复制所有数据或释放之前的内存:
node->stringList = realloc(node->stringList, (node->stringcount+1)*sizeof(char*));
node->stringList[node->stringcount] = (char*)string;
我写了一个简单的 C 代码,它应该在一个结构中存储一个字符串地址列表 (char*)。该列表是动态的,所以每次添加一个新字符串时,我都会预留足够的内存来存储所有当前字符串地址加上新地址。然后我释放旧缓冲区并将新缓冲区分配给结构。问题是它在 free() 上崩溃。
我确信我有空()ing我从calloc()得到的确切地址,但它仍然崩溃了。
这是输出:
main(3618,0x7fff7a83f300) malloc: *** error for object 0x7f9902404bd0: incorrect checksum for freed object - object was probably modified after being freed.
密码是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct StructNODE{
char** stringlist;
int stringcount;
struct StructNODE* next;
} NODE;
void Addstring(NODE* node, const char* string)
{
int currentBufferSize = node->stringcount * sizeof(char*);
// make room for the current string list plus the new one
char** addrList = (char**) calloc( 1, currentBufferSize );
printf("malloc: %d bytes starting at 0x%X\n",currentBufferSize, addrList);
// copy all current addresses to the new list
memcpy(addrList, node->stringlist, currentBufferSize);
printf("freeing mem at 0x%X\n",node->stringlist);
free(node->stringlist);
// Append the new address to the end of the address buffer
addrList[node->stringcount] = (char*)string;
//make the node point to the new buffer
node->stringlist = addrList;
// Increment the string number counter
node->stringcount++;
}
void PrintStringlist(NODE* node)
{
int i;
for ( i=0; i < node->stringcount; i++)
{
printf("string %d: %s\n",i, node->stringlist[i]);
}
}
int main(int argc, char** argv)
{
NODE* node = (NODE*) calloc(1 , sizeof(NODE));
Addstring(node, "Lewis Skolnick");
Addstring(node, "Gilbert Lowe");
Addstring(node, "Arnold Poindexter");
Addstring(node, "Harold Wormser");
Addstring(node, "Booger");
Addstring(node, "Takashi Toshiro");
Addstring(node, "Lamar Latrelle");
Addstring(node, "Judy");
PrintStringlist(node);
return 0;
}
我忽略了什么?
您的缓冲区太小 - 您忘记为额外元素添加 space。第一个函数行应该是:
int currentBufferSize = (node->stringcount + 1) * sizeof(char*);
calloc
的签名如下:
void* calloc (size_t num, size_t size);
因此,假设 stringcount
是实际金额,您应该使用不同的参数调用它,例如
calloc(sizeof(char*), node->stringcount +1)
无论如何,stdlib 中还有另一个有用的函数 realloc
,它允许您直接调整分配的内存大小,而无需自己复制所有数据或释放之前的内存:
node->stringList = realloc(node->stringList, (node->stringcount+1)*sizeof(char*));
node->stringList[node->stringcount] = (char*)string;