首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内存自由抛出segFault

内存自由抛出segFault
EN

Stack Overflow用户
提问于 2014-02-06 16:58:13
回答 1查看 205关注 0票数 0

我使用链接列表实现符号表,代码工作正常,但是代码中有内存泄漏,

我有以下结构

结构节点{ char* pcKey;void* pvValue;struct节点*next;};struct _Sym { int totalBindings;struct节点*节点;};

添加我有sym_new方法为sym实例分配内存

代码语言:javascript
复制
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
}

我正在根据字符串长度为其他函数中的键和值分配内存。

自由方法是

代码语言:javascript
复制
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文件

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-06 17:06:27

变量pcKeypvValue可能应该在Sym_new()函数中初始化为null。否则,它们可能包含任何旧值。这是因为malloc不一定将分配的内存为零:它只是分配一块内存,因此内存可能会被垃圾填满。

因此,如果由于某种原因没有为新创建的对象调用sym_put(),这些指针可能指向无效内存,并在调用free()段错误时指向错误。如果将它们初始化为nullfree()就会忽略它们,而不会试图释放内存。

一种仅用于检查pcKeypvValue变量是否由sym_put调用分配的"hacky“调试技术是在sym_new中使用虚拟值初始化它们,例如0xCDCDCDCD (注意指针宽度).这就是为什么我说这是一种讨厌的技术)。然后在sym_free中,在释放pcKeypvValue之前检查这个神奇常量。如果你找到了,就会有问题.

同样令人感兴趣的是线程https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc

编辑:

查看链接的代码,您似乎是丢弃了const

函数id定义为:

代码语言:javascript
复制
int SymTable_put (SymTable_t m_SymTable_t, const char *pcKey, const void *pvValue)

但是这个演员..。

代码语言:javascript
复制
temp->pcKey = (char*)pcKey;
temp->pvValue = (char*)pvValue;

这是个坏主意。你在“愚弄”编译器使你的承诺无效。

BUG: Ok,因此您按以下方式分配

代码语言:javascript
复制
temp->pcKey = (char*) malloc (sizeof(char) * strlen (pcKey));

但是,然后使用

代码语言:javascript
复制
temp->pcKey = (char*)pcKey;

所以你( a)有一个内存泄漏和b)只是存放错误的指针,这就是为什么你得到分段错误。您可能打算做的是(https://stackoverflow.com/questions/252782/strdup-what-does-it-do-in-c在这里很有用)..。

代码语言:javascript
复制
temp->pcKey = strdup(pcKey);

这将为pcKey中的字符串分配新内存,并将字符串复制到新内存中。

我猜你会这样称呼这个函数.

代码语言:javascript
复制
SymTable_put (xxx, "KEY string", "VALUE string");

然后你的代码就这样做了

代码语言:javascript
复制
temp->pcKey = (char*)malloc (sizeof(char) * strlen (pcKey));
...
temp->pcKey = (char*)pcKey;

因此,现在temp->pcKey指向“键字符串”本身,而不是它的副本。因此,当您尝试释放字符串常量时,您的程序会发出抱怨。您要做的是将字符串从pcKey复制到temp->pcKey,而不是覆盖指针。

编辑:根据注释,malloc需要空间+1来包含空终止符。同时,sizeof(char)总是1,所以是冗余的。尝试strdup instread。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21609215

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档