Valgrind报告了realloc调用的内存泄漏。但无法理解为什么

时间:2013-12-02 03:00:01

标签: c memory-leaks malloc valgrind realloc

我有一个结构如下:

typedef struct somefruits{
 struct pine abc;
 int xyz;
}pm;

struct pine 
{
    unsigned char *ch;
    unsigned char *data;
    unsigned int a;
}

int function(unsigned int nfruits, pm **outfruits)
 {
  pm *fruits = NULL;
  status = 0;
  void *tmp = NULL;
  tmp = realloc(fruits, (nfruits + 1) * sizeof *fruits);
  if (tmp != NULL)
  fruits = tmp;

  //do some manipulations on fruits. malloc and assign values for ch and data;

   for (i =0 ;i<nfruits;i++)
   {
       // do some stuff
       fruits[i]->abc.data = malloc(20);
       //write some stuff into data

       fruits[i]->abc.ch = malloc(100);
        //write some stuff into ch 
   }
  //do manipulations which can result in change of status variable 

  *outfruits =  fruits;

 return status;
}

 int main ()
 {
    pm *Fmain;
    function(10, &Fmain);

     // do some stuff with Fmain
    dispose(Fmain, 10);
 }

 dispose(pm *object, int n)
 {
   for(i=0;i<n;i++)
   {
       free((object+i)->abc.ch);
       free ((object+i)->abc.data);
   }
     free (object);
 }

当我在以下代码上运行valgrind时,我得到了

    HEAP SUMMARY:
  ==4699== 421 (352 direct, 69 indirect) bytes in 1 blocks are definitely lost in loss record 3 of 4
  ==4699==    by 0x4A079DA: realloc 
  ==4699==    by 0x40A065: function (file1.c:623)

第623行指向tmp = realloc(fruits, (nfruits + 1) * sizeof *fruits)

由于我释放处置中的内存,我无法理解我做错了什么。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

在重写问题之前!

真的不是那么难。这段代码编写得很干净;它也在valgrind下干净利落地运行。请注意,struct pinestruct somefruit的定义与其他细节问题相比,必须相反。

#include <stdlib.h>

struct pine
{
    unsigned char ch;
    unsigned char data;
    unsigned int a;
};

typedef struct somefruits
{
    struct pine abc;
    int xyz;
} pm;

void function(unsigned nfruits, pm **outfruits);
void dispose(pm * object);

void function(unsigned nfruits, pm **outfruits)
{
    pm *fruits = malloc((nfruits + 1) * sizeof *fruits);
    if (fruits != NULL)
    {
        for (unsigned i = 0; i < nfruits + 1; i++)
        {
            fruits[i].xyz = i;
            fruits[i].abc.ch = i + 'A';
            fruits[i].abc.data = i + 'a';
            fruits[i].abc.a = i + 237;
        }
    }
    *outfruits =  fruits;
}

void dispose(pm * object)
{
    free(object);
}

int main(void)
{
    pm *Fmain;
    function(10, &Fmain);

    dispose(Fmain);
    return 0;
}

问题被重写后!

#include <stdlib.h>

struct pine
{
    unsigned char *ch;
    unsigned char *data;
    unsigned int a;
};

typedef struct somefruits
{
    struct pine abc;
    int xyz;
} pm;

void function(unsigned nfruits, pm **outfruits);
void dispose(unsigned nfruits, pm *object);

void function(unsigned nfruits, pm **outfruits)
{
    pm *fruits = malloc((nfruits + 1) * sizeof *fruits);
    if (fruits != NULL)
    {
        for (unsigned i = 0; i < nfruits + 1; i++)
        {
            fruits[i].xyz = i;
            fruits[i].abc.ch = malloc(20);
            fruits[i].abc.data = malloc(20);
            fruits[i].abc.a = i + 237;
            if (fruits[i].abc.ch != 0)
                fruits[i].abc.ch[0] = '\0';
            if (fruits[i].abc.data != 0)
                fruits[i].abc.data[0] = '\0';
        }
    }
    *outfruits =  fruits;
}

void dispose(unsigned nfruits, pm *object)
{
    for (unsigned i = 0; i < nfruits + 1; i++)
    {
        free(object[i].abc.ch);
        free(object[i].abc.data);
    }
    free(object);
}

int main(void)
{
    pm *Fmain;
    function(10, &Fmain);

    dispose(10, Fmain);
}

nfruits + 1的废话非常危险。代码是一致的,但+1不是好设计。此代码也具有来自valgrind的健康清单。