Reputation: 409
I have a struct as follows:
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);
}
When I run valgrind on the following code I get
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)
Line 623 points to tmp = realloc(fruits, (nfruits + 1) * sizeof *fruits)
line
Since I am freeing the memory in dispose I am unable to understand what it is that I am doing wrong. Any help will be much appreciated.
Upvotes: 0
Views: 379
Reputation: 753970
It really isn't all that hard. This code compiles cleanly; it also runs cleanly under valgrind
. Note that the definitions of struct pine
and struct somefruit
had to be reversed compared to the question, amongst other minutiae.
#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);
}
The nonsense with nfruits + 1
is downright dangerous. The code is consistent, but the +1
is not good design. This code too has a clean bill of health from valgrind
.
Upvotes: 1