动态字符串列表和 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;