2013-08-05 59 views
0

我用Valgrind找到我的程序中的內存泄漏。最重要的功能如下:內存泄漏replaceAll在C

char *replaceAll (const char *string, const char *substr, const char *replacement){ 
    char *tok = NULL; 
    char *newstr = NULL; 
    char *oldstr = NULL; 
    char *strhead = NULL; 
    // if either substr or replacement is NULL, duplicate string and let caller handle it 
    if (substr == NULL || replacement == NULL) return strdup (string); 
    newstr = strdup (string); 
    strhead = newstr; 
    while ((tok = strstr (strhead, substr))) { 
    oldstr = newstr; 
    newstr = malloc(strlen(oldstr) - strlen(substr) + strlen(replacement) + 1); 
    // failed to alloc mem, free old string and return NULL 
    if (newstr == NULL){ 
     free (oldstr); 
     return NULL; 
    } 
    memcpy (newstr, oldstr, tok - oldstr); 
    memcpy (newstr + (tok - oldstr), replacement, strlen (replacement)); 
    memcpy (newstr + (tok - oldstr) + strlen(replacement), tok + strlen (substr), strlen (oldstr) - strlen (substr) - (tok - oldstr)); 
    memset (newstr + strlen (oldstr) - strlen (substr) + strlen (replacement) , 0, 1); 
    // move back head right after the last replacement 
    strhead = newstr + (tok - oldstr) + strlen(replacement); 

    free (oldstr); 
    } 
    return newstr; 
} 

int transformRegex(char **regexS){ 

    char* retS; 
    retS = (char*) malloc(400); 
    memset(retS, 0x00, 400); 

    retS = replaceAll(*regexS, ".", "\\."); 

    if (strstr(*regexS, "*")) { 
     retS = replaceAll(retS, "**", "@"); 
     retS = replaceAll(retS, "*", "[^\\.]ß"); 
     retS = replaceAll(retS, "ß", "*"); 
     retS = replaceAll(retS, "@", ".*"); 
    } 

    if(strstr(*regexS, "%")){ 
     retS = replaceAll(retS, "%", "[^\\.]{1}"); 
    } 

    char tmpStr[strlen(retS)+3]; 
    memset(tmpStr, 0x00, strlen(retS)+3); 
    memcpy(tmpStr, "^", 1); 
    memcpy(&tmpStr[1], retS, strlen(retS)); 
    strcat(tmpStr, "$"); 
    memcpy(*regexS, tmpStr, strlen(tmpStr)); 

    free(retS); 

    return 0; 
} 

現在Valgrind的報告我

==29218== 129 bytes in 5 blocks are definitely lost in loss record 6 of 9 
==29218== at 0x4C27DD0: malloc (vg_replace_malloc.c:270) 
==29218== by 0x400A64: **replaceAll** (regcomptest.c:44) 
==29218== by 0x400C61: **transformRegex** (regcomptest.c:141) 
==29218== by 0x400F9F: main (regcomptest.c:221) 
==29218== 
==29218== 134 bytes in 5 blocks are definitely lost in loss record 7 of 9 
==29218== at 0x4C27DD0: malloc (vg_replace_malloc.c:270) 
==29218== by 0x400A64: **replaceAll** (regcomptest.c:44) 
==29218== by 0x400C34: **transformRegex** (regcomptest.c:136) 
==29218== by 0x400F9F: main (regcomptest.c:221) 
==29218== 
==29218== 6,000 bytes in 15 blocks are definitely lost in loss record 9 of 9 
==29218== at 0x4C27DD0: **malloc** (vg_replace_malloc.c:270) 
==29218== by 0x400C07: **transformRegex** (regcomptest.c:132) 
==29218== by 0x400F9F: main (regcomptest.c:221) 

其中記錄9指的malloc(400)調用。爲什麼它是400 * ,爲什麼當我說free(retS)時會泄漏?我該如何正確實現這一點,以便replaceAll不會泄漏內存?由於transformRegex通過引用更改參數,因此應該在函數的末尾釋放任何臨時變量。但我不知道如何,我的Java過去塊在思考;)

回答

3
retS = (char*) malloc(400); 

你從來沒有釋放這部分內存。

strdup複製字符串使用malloc。當您的免費oldstr,您可以通過strdup

釋放內存的alloc可以後newstr = strdup (string);

添加free(string);或者你可以使用一個變量來存儲RES。比如:char *reSS = reS ;只是在調用malloc之後。然後你在主結束時釋放reSS。

+0

+1。請注意,每次調用'replaceAll' – simonc

+0

後,我還需要釋放'retS'(每個replaceAll或free(string)後都有空)我得到錯誤。我的想法是有一個輔助變量retS,它被分配一次並最終釋放。我怎樣才能釋放它 - 每次replaceAll後 - 如果我仍然需要使用它? – dasLort

+0

@dasLort您可以使用指針來存儲reS。像char * reSS = reS.Then最終釋放reSS –