>我正在使用链接列表实现符号表,代码工作正常,但代码中存在内存泄漏,
我有以下结构
struct node { char* pcKey; void* pvValue; struct node *next; }; struct _Sym { int totalBindings; struct node *node; };
添加我有sym_new为符号实例分配内存的方法
sym Sym_new (void)
{
_Sym *m_SymTable_t = (_Sym*) malloc (sizeof(_Sym));
if(m_SymTable_t == NULL)
{
return NULL;
}
else
{
m_SymTable_t->totalBindings = 0;
m_SymTable_t->node = NULL;
return m_SymTable_t;
}//endif
}
我正在根据字符串长度为其他函数中的键和值分配内存。
免费方法是
typedef struct _Sym *Sym;
void Sym_free (Sym m_SymTable_t)
{
assert(m_SymTable_t != NULL);
struct node* temp = m_SymTable_t->node;
struct node *currentBinding = NULL;
while(temp != NULL)
{
currentBinding = temp;
temp = temp -> next;
//Removing comment for the below line throws segfault
//free(currentBinding -> pcKey);
//free(currentBinding -> pvValue);
free(currentBinding);
}
free(m_SymTable_t);
}
完全释放符号的正确方法是什么?
我已经在链接上传了我的symTable_Link.cpp文件
变量pcKey
和pvValue
可能应该初始化为Sym_new()
函数中的null
。否则,它们可能包含任何旧值。这是因为malloc
不一定将分配的内存归零:它只是分配了一大块内存,因此内存可能会被垃圾填满。
因此,如果由于某种原因没有为新创建的对象调用sym_put()
这些指针可能会指向无效内存,并在您调用free()
段错误时。如果您将它们初始化为null
free()
只会忽略它们,并且不会尝试释放内存。
您可以使用一种"hacky">仅调试技术来检查pcKey
和pvValue
变量是否肯定是由sym_put
调用分配的,方法是使用虚拟值sym_new
初始化它们,例如0xCDCDCDCD(请注意这里的指针宽度...这就是为什么我称之为黑客技术)。然后在sym_free
在释放pcKey
和pvValue
之前检查这个魔术常数。如果你找到它,那就是问题所在...
同样有趣的可能是线程我是否投射了 malloc 的结果?
编辑:
查看链接的代码,您似乎正在丢弃 const!
函数 ID 定义为:
int SymTable_put (SymTable_t m_SymTable_t, const char *pcKey, const void *pvValue)
但是这个演员表...
temp->pcKey = (char*)pcKey;
temp->pvValue = (char*)pvValue;
这是个坏主意。您正在"愚弄"编译器,使其使您的 const 承诺无效。
错误:好的,所以你分配如下
temp->pcKey = (char*) malloc (sizeof(char) * strlen (pcKey));
但随后你使用
temp->pcKey = (char*)pcKey;
所以你 a) 有内存泄漏和 b) 刚刚藏了错误的指针,这可能是你得到段错误的原因。你可能打算做的是(strdup在这里很有用)......
temp->pcKey = strdup(pcKey);
这将为pcKey
中的字符串分配新内存,并将字符串复制到新内存中。
我猜你这样称呼这个函数......
SymTable_put (xxx, "KEY string", "VALUE string");
然后你的代码这样做了
temp->pcKey = (char*)malloc (sizeof(char) * strlen (pcKey));
...
temp->pcKey = (char*)pcKey;
所以现在temp->pcKey
指向"KEY 字符串"本身,而不是它的副本。因此,当您尝试释放字符串常量时,您的程序会抱怨。您要做的是将字符串从pcKey
复制到temp->pcKey
,而不是覆盖指针。
编辑: 根据注释,malloc
需要空格 + 1 才能包含空终止符。此外,sizeof(char)
始终为 1,因此是多余的。尝试strdup
内在。