C语言链表结构中安全释放值的策略

Strategies for safely free-ing values in a linked-list structure in C

我使用 C 将大量数据存储在链表结构中。链表中的某些项目指向相同的 malloc 数据,这在释放链表结构时会导致问题。我可以通过复制插入链表结构的数据来解决这个问题,但这对我的程序有更大的影响。

也就是说:我 运行 关注这个问题的事实表明我有设计问题。因此,我正在寻找有助于解决此问题的策略和建议。

这里有一些代码突出了这个问题(是的,我知道我不应该像这样盲目地转换 malloc):

char *val = (char *)malloc(256);
strcpy(val, "Dummy value");

LinkedListItem *itemB = (LinkedListItem *)malloc(sizeof(LinkedListItem));
itemB->value = val;
itemB->next = NULL;

LinkedListItem *itemA = (LinkedListItem *)malloc(sizeof(LinkedListItem));
itemA->value = val;
itemA->next = itemB;

LinkedListItem *cur = itemA;
while(cur)
{
    free(cur->value); // the crash will occur here, when performing a double free on itemB's value pointer
    cur->value = NULL;

    cur = cur->next;
}

我看到很多关于 'safe' 版本的 free 的引用,在释放它之后基本上是 NULL 指针,像这样:

void free_generic(void **pp)
{
    assert(pp);

    if(pp != NULL)
    {
        free(*pp);
        *pp = NULL;
    }
}

while(cur)
{
    free_generic(&cur->value);
    cur = cur->next;
}

不过这个好像没什么效果。有什么建议吗?

这就是引用计数的用途。

每次分配东西时都使用这个结构:

struct AllocatedStringValue {
    char* string;
    size_t refCount;
};


struct AllocatedStringValue value;
value.refCount = 0;
value.string = calloc( 256, sizeof(char) );

LinkedListItem *itemB = (LinkedListItem *)malloc(sizeof(LinkedListItem));
itemB->value = value;
itemB->next = NULL;
value.refCount++;

...

itemA->value = value;
value.refCount++;

...

while(cur) {
    if( cur->value.refCount > 0 ) {
        cur->value.refCount--;
    } else {
        free( cur->value->string );
    }
}

关于这段代码。

void free_generic(void **pp)
{
    assert(pp);       // this and following 'if' are testing same thing
                      // and this assert() should never fail as
                      // 'pp' is the address of a variable

    if(pp != NULL)    // could only fail if variable located at address 0
                      // should be: 'if( *pp )'
    {
        free(*pp);
        *pp = NULL;
    }
}

while(cur)
{
    free_generic(&cur->value);
    cur = cur->next;
}