[英]Correct way to free memory for a structure that contains allocated memory referenced by pointers
我有以下功能:
/* 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
分配的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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.