我使用 Valgrind 在我的程序中查找内存泄漏。重要功能如下:
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* 15,为什么当我说 free(retS) 时它会泄漏?以及如何正确实现这一点,以便 replaceAll 不会泄漏内存?因为 transformRegex 通过 Reference 改变了参数,所以任何临时变量都应该在函数结束时被释放。但我不知道怎么做,我的 Java 过去阻碍了 C 的思考;)