2014-02-06 32 views
0

我使用的鏈接列表,代碼工作正常,但在代碼中的內存泄漏執行符號表,內存罰球段錯誤

我有以下結構

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 
} 

我爲鍵a分配內存nd基於字符串長度的其他函數中的值。

免費的方法是

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文件在鏈接

+1

看起來你沒有在分配器函數中初始化pcKey和pvValue爲NULL? – Jarhmander

+0

也有用可能是:http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc - 爲什麼不投出'malloc'的返回。這不是什麼錯誤的代碼...只是一個評論 – Jimbo

+0

你在哪裏分配pcKey和pvValue的內存?另外,*請*不要使用匈牙利符號來編碼變量名稱中的原始類型信息;這不是它的意思。 –

回答

1

變量pcKeypvValue也許應該在Sym_new()函數初始化爲null。否則,它們可能包含任何舊值。這是因爲malloc不一定會分配內存爲零:它只是分配一塊內存,因此內存可能會被垃圾填滿。

因此,如果由於某種原因,sym_put()不針對新創建的對象調用,這些指針可能指向無效內存,並且在您調用free()段錯誤時。如果將它們初始化爲nullfree()將會忽略它們,並且不會嘗試釋放內存。

A「哈克」 DEBUG-只有技術,你可以用它來檢查由sym_put電話說pcKeypvValue變量絕對分配將初始化它們sym_new與虛值,例如0xCDCDCDCD(小心指針寬度在這裏...這就是爲什麼我稱這是一個哈克技術)。然後在sym_free檢查這個魔術常數,然後釋放pcKeypvValue。如果你覺得,有個問題......

也感興趣的可能是線程Do I cast the result of malloc?

編輯:

在鏈接的代碼看去,你似乎是丟棄常量

功能ID定義爲:

int SymTable_put (SymTable_t m_SymTable_t, const char *pcKey, const void *pvValue) 

但後來這是否投...

temp->pcKey = (char*)pcKey; 
temp->pvValue = (char*)pvValue; 

這是一個壞主意。你在「愚弄」編譯器使你的const承諾失效。

的Bug: 好了,所以你分配如下

temp->pcKey = (char*) malloc (sizeof(char) * strlen (pcKey)); 

但你覆蓋使用

temp->pcKey = (char*)pcKey; 

所以你一個)有內存泄漏這個指針,和b)具有隻是隱藏了錯誤的指針,這是probs爲什麼你得到段錯誤。你,你可能打算做的卻是(strdup在這裏很有用)...

temp->pcKey = strdup(pcKey); 

這將在pcKeyCOPY字符串分配的字符串新內存插入新的內存。

我會哈扎德一個你叫這樣的函數猜測...

SymTable_put (xxx, "KEY string", "VALUE string"); 

那麼你的代碼做這個

temp->pcKey = (char*)malloc (sizeof(char) * strlen (pcKey)); 
... 
temp->pcKey = (char*)pcKey; 

所以現在temp->pcKey點「密鑰字符串」本身並沒有它的副本是。所以當你試圖釋放字符串常量時,你的程序會抱怨。你想要做的是拷貝pcKeytemp->pcKey的字符串,而不是覆蓋指針。

編輯: 根據評論malloc s需要空間+ 1包括空終止符。另外sizeof(char)總是1,所以是多餘的。嘗試strdup未讀。

+0

我可以看到pcKey和pvValue的有效地址,確切的實現http:// tempsend.com/62CCDBF79A – Meluha

+0

好吧,我想我看到你的bug。請看答案編輯:) – Jimbo

+2

你需要爲'strlen + 1'提供'malloc' - 不要忘記''\ 0''終止符。 – Floris