[英]Strategies for safely free-ing values in a linked-list structure in C
Using C I'm storing a large amount of data in a linked list structure. 使用C,我将大量数据存储在链表结构中。 Some items in the linked list point to the same malloc'd data and this is causing issues when it comes to free-ing the linked list structure.
链表中的某些项指向相同的已分配数据,这在释放链表结构时引起问题。 I could solve the issue by copying the data as it's inserted into the linked list structure, but this has bigger implications for my program.
我可以通过复制插入链表结构中的数据来解决该问题,但这对我的程序有更大的影响。
That said: the fact that I'm running into this issue suggests I have a design problem. 就是说:我遇到这个问题的事实表明我有一个设计问题。 As such, I'm looking for strategies and suggestions to help deal with this problem.
因此,我正在寻找有助于解决此问题的策略和建议。
Here's some code that highlights the issue (and yes, I know that I shouldn't be blindly casting malloc
like this): 这是一些突出问题的代码(是的,我知道我不应该像这样盲目地投射
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;
}
I've seen many references to a 'safe' version of free that essentially NULL's the pointer after free-ing it, like so: 我已经看到许多关于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;
}
But this seems to have no effect. 但这似乎没有效果。 Any suggestions?
有什么建议么?
This is what reference-counting is for. 这就是引用计数的目的。
Use this struct every time you allocate something: 每次分配一些东西时都使用此结构:
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 );
}
}
regarding this code snippit. 关于此代码段。
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.