内存免费抛出segFault

时间:2014-02-06 16:58:14

标签: c malloc

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

我有以下结构

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文件

1 个答案:

答案 0 :(得分:1)

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

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

“hacky”仅限DEBUG 技术可用于检查free()pcKey变量是否由pvValue调用明确分配用虚拟值在sym_put中初始化它们,例如0xCDCDCDCD(注意这里的指针宽度......这就是我称之为hacky技术的原因)。然后在sym_new中检查此魔术常数,然后释放sym_freepcKey。如果你找到它,就会出现问题......

感兴趣的还有线程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。

相关问题