0

我使用 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 的思考;)

4

1 回答 1

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

你永远不会释放这部分内存。

strdup复制字符串使用malloc. 当你释放 oldstr 时,你释放内存分配strdup

free(string);之后可以添加newstr = strdup (string);

或者您可以使用变量来存储 reS 。喜欢:char *reSS = reS ;就在调用malloc之后。然后在 main 结束时释放 reSS。

于 2013-08-05T10:25:17.497 回答