我有以下功能:
/* undef: from s from hashtab */
void undef(char *s) {
struct nlist *currentPtr, *previousPtr;
for (previousPtr = NULL, currentPtr = hashtab[hash(s)];
currentPtr != NULL;
previousPtr = currentPtr, currentPtr = currentPtr->next) {
if (strcmp(currentPtr->name, s) == 0) {
if (previousPtr == NULL) /* first element */
hashtab[hash(s)] = currentPtr->next;
else /* element in the middle or at the end */
previousPtr->next = currentPtr->next;
/* free memory */
free(currentPtr->name);
free(currentPtr->defn);
//free(currentPtr);
}
}
}
currentPtr
指向由malloc
分配的内存。
currentPtr->name
和 currentPtr->defn
指向通过 strdup
复制的字符数组。
我不确定释放列表项内存的正确方法是什么。
如果我用
free(currentPtr->name);
free(currentPtr->defn);
然后我没有出现段错误,但我相信字符数组内存已被释放,但列表结构元素本身却没有。
如果我用
free(currentPtr);
然后我也没有出现段错误,但我相信我释放了列表结构元素本身,但没有释放字符数组内存。
使用
free(currentPtr->name);
free(currentPtr->defn);
free(currentPtr);
给我段错误。但我认为这是正确的做法。
那么哪个是正确的呢?为什么会失败?
最佳答案
你需要稍微改变你的策略,因为 currentPtr
是调用之后的悬空指针
free(currentPtr);
这是我的建议:
for (previousPtr = NULL, currentPtr = hashtab[hash(s)];
currentPtr != NULL;
previousPtr = currentPtr) {
if (strcmp(currentPtr->name, s) == 0)
{
if (previousPtr == NULL) /* first element */
hashtab[hash(s)] = currentPtr->next;
else /* element in the middle or at the end */
previousPtr->next = currentPtr->next;
/* free memory */
free(currentPtr->name);
free(currentPtr->defn);
// Get hold of the next pointer before free'ing currentPtr
struct nlist *tempPtr = currentPtr->next;
free(currentPtr);
currentPtr = tempPtr;
}
else
{
currentPtr = currentPtr->next;
}
}
更新,更精简的版本
由于您在四个地方使用了 currentPtr->next
,因此您可以使用以下方法简化循环:
struct nlist *nextPtr = NULL;
for (previousPtr = NULL, currentPtr = hashtab[hash(s)];
currentPtr != NULL;
previousPtr = currentPtr, currentPtr = nextPtr) {
nextPtr = currentPtr->next;
if (strcmp(currentPtr->name, s) == 0)
{
if (previousPtr == NULL) /* first element */
hashtab[hash(s)] = nextPtr;
else /* element in the middle or at the end */
previousPtr->next = nextPtr;
/* free memory */
free(currentPtr->name);
free(currentPtr->defn);
free(currentPtr);
}
}
关于为包含指针引用的已分配内存的结构释放内存的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38904871/