我正在使用链接列表实现符号表,代码工作正常,但代码中存在内存泄漏,
我有以下结构
struct node { char* pcKey; void* pvValue; struct node *next; }; struct _Sym { int totalBindings; struct node *node; };
添加我有sym_new方法为sym实例分配内存
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);
}
完全释放sym的正确方法是什么?
我已在链接
上传了我的symTable_Link.cpp文件答案 0 :(得分:1)
变量pcKey
和pvValue
可能应该在null
函数中初始化为Sym_new()
。否则,它们可能包含任何旧值。这是因为malloc
不一定将分配的内存归零:它只分配一块内存,因此内存可以填充垃圾。
因此,如果由于某种原因{@ 1}}没有为新创建的对象调用,则这些指针可能指向无效的内存并且在您调用sym_put()
段错误时。如果您将它们初始化为free()
null
,则会忽略它们,并且不会尝试释放内存。
“hacky”仅限DEBUG 技术可用于检查free()
和pcKey
变量是否由pvValue
调用明确分配用虚拟值在sym_put
中初始化它们,例如0xCDCDCDCD(注意这里的指针宽度......这就是我称之为hacky技术的原因)。然后在sym_new
中检查此魔术常数,然后释放sym_free
和pcKey
。如果你找到它,就会出现问题......
感兴趣的还有线程Do I cast the result of malloc?
编辑:
查看链接的代码,您似乎丢弃const !
函数id定义为:
pvValue
但是这会导致......
int SymTable_put (SymTable_t m_SymTable_t, const char *pcKey, const void *pvValue)
这是一个坏主意。你正在“愚弄”编译器使你的const承诺无效。
BUG: 好的,所以按照以下方式分配
temp->pcKey = (char*)pcKey;
temp->pvValue = (char*)pvValue;
然后你用
覆盖这个指针temp->pcKey = (char*) malloc (sizeof(char) * strlen (pcKey));
所以你a)有一个内存泄漏和b)刚刚藏匿错误的指针,这是probs为什么你得到段错误。您可能打算这样做(strdup在这里很有用)......
temp->pcKey = (char*)pcKey;
这将为temp->pcKey = strdup(pcKey);
中的字符串分配新内存,并将字符串 COPY 分配到新内存中。
我会骂你猜这个函数就像这样......
pcKey
然后你的代码做了这个
SymTable_put (xxx, "KEY string", "VALUE string");
所以现在temp->pcKey = (char*)malloc (sizeof(char) * strlen (pcKey));
...
temp->pcKey = (char*)pcKey;
指向“KEY string”本身而不指向它的副本。因此,当您尝试释放字符串常量时,您的程序会抱怨。您要做的是将<{1}}中的字符串复制到temp->pcKey
而不是覆盖指针。
编辑:
根据评论,pcKey
需要空格+ 1来包含空终止符。此外temp->pcKey
始终为1,因此是多余的。试试malloc
instread。