代码之家  ›  专栏  ›  技术社区  ›  citronas

这段代码中的内存泄漏在哪里?如何修复它?

  •  7
  • citronas  · 技术社区  · 14 年前

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int main(int argc, char* argv[] )
    {
     char* output = "\0";
     int counter = 5;
      while(counter > 0)
      {
          char buffer[20];
          sprintf(buffer, "%u", counter);
          char* temp;
          temp = malloc((strlen(output) + strlen(buffer) + 1));
          strcpy(temp, buffer);
          strcat(temp, output);
          char* oldmemory = output;
          output = temp;
          free(oldmemory);
          counter--;
      }
    printf("output: %s\n", output);
    free(output);
    return 0;
    }
    

    退货:

    ==7125== Memcheck, a memory error detector
    ==7125== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
    ==7125== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
    ==7125== Command: ./foo
    ==7125== Parent PID: 4455
    ==7125== 
    ==7125== Invalid free() / delete / delete[]
    ==7125==    at 0x4024B3A: free (vg_replace_malloc.c:366)
    ==7125==    by 0x8048662: main (foo.c:20)
    ==7125==  Address 0x8048780 is not stack'd, malloc'd or (recently) free'd
    ==7125== 
    ==7125== 
    ==7125== HEAP SUMMARY:
    ==7125==     in use at exit: 0 bytes in 0 blocks
    ==7125==   total heap usage: 5 allocs, 6 frees, 20 bytes allocated
    ==7125== 
    ==7125== All heap blocks were freed -- no leaks are possible
    ==7125== 
    ==7125== For counts of detected and suppressed errors, rerun with: -v
    ==7125== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 15 from 8)
    

    内存泄漏在哪里?如何修复?

    4 回复  |  直到 14 年前
        1
  •  9
  •   Philip Potter    14 年前
    #include <stdio.h>
    #include <stdlib.h>
    int main(int argc, char* argv[] )
    {
     char* output = "\0";
    

     int counter = 5;
      while(counter > 0)
      {
          char buffer[20];
          sprintf(buffer, "%u", counter);
          char* temp;
          temp = malloc((strlen(output) + strlen(buffer) + 1));
          strcpy(temp, buffer);
          strcat(temp, output);
          char* oldmemory = output;
          output = temp;
          free(oldmemory);
    

    这是我第一次 free() 调用时,释放输出的初始值,即指向字符串文字的指针 "\0" . 打电话 在从返回的有效指针以外的任何对象上 *alloc() NULL 是未定义的行为。

          counter--;
      }
    printf("output: %s\n", output);
    free(output);
    return 0;
    }
    

    valgrind报告:

    ==7125== Invalid free() / delete / delete[]
    ==7125==    at 0x4024B3A: free (vg_replace_malloc.c:366)
    ==7125==    by 0x8048662: main (foo.c:20)
    ==7125==  Address 0x8048780 is not stack'd, malloc'd or (recently) free'd
    

    免费() .

        2
  •  4
  •   sizzzzlerz    14 年前

    你的密码坏了。第一步,将oldmemory设置为output,其中output指向堆上未分配的内存。稍后,您将尝试释放此内存。这将生成关于释放未通过malloc分配的内存的valgrind错误。因此,您分配的原始内存永远不会被释放。

        3
  •  3
  •   bramp Madhur Ahuja    14 年前

    不要使用malloc和strcpy,请看realloc,它可以做您想要做的一切,但更好:)但是您很可能希望向前构建字符串(counter=0;counter<5;count++),而不是向后

        4
  •  1
  •   Logan Capaldo    14 年前

    如果要使用此算法,则应使用malloc分配输出点的初始空间,因此:

     char *output = malloc(1);
     if(!output) { /* handle error */ }
     output[0] = '\0';
     ... rest of code as is ...
    

    字符串文字未分配给 malloc ,因此不能 free 埃德,这是你问题的根源。