Вы не инициализируете выделенную память в показанном вами коде. В общем случае вы получаете ненулевой мусор, выделенный malloc()
. Если вам нужна нулевая память, используйте calloc()
.
Существует также проблема, выявленная в ответе JCooper .
Существует также проблема, указанная в комментарии Muggen .
Вы освобождаете предметы в стеке, но не в стопках в целом. Это должно быть сделано внутри цикла for (i2 = 0; ...)
, но после цикла for (k2 = 0; ...)
.
В совокупности это составляет небольшую катастрофу.
После редактирования кода ...
Следующий код компилируется и запускается чистым:
$ cc -Wall -Wextra -g -O3 -std=c99 x.c -o x
$ valgrind ./x
==16593== Memcheck, a memory error detector.
==16593== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==16593== Using LibVEX rev 1658, a library for dynamic binary translation.
==16593== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==16593== Using valgrind-3.2.1, a dynamic binary instrumentation framework.
==16593== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==16593== For more details, rerun with: -v
==16593==
==16593==
==16593== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 5 from 1)
==16593== malloc/free: in use at exit: 0 bytes in 0 blocks.
==16593== malloc/free: 2,201 allocs, 2,201 frees, 40,032 bytes allocated.
==16593== For counts of detected errors, rerun with: -v
==16593== All heap blocks were freed -- no leaks are possible.
$
Рабочий код
#include <stdlib.h>
#include <stdio.h>
#define push(s, ele) ((s).list[((s).last)++] = (ele))
typedef struct vp
{
short v1;
short v2;
} VPTYPE;
typedef struct VPLIST
{
int last;
VPTYPE **list;
} VPLISTTYPE;
enum { nof = 2 };
int main(void)
{
VPLISTTYPE *v1v2 = (VPLISTTYPE *)malloc(sizeof(*v1v2) * nof);
for (int i = 0; i < nof; i++)
v1v2[i].last = 0;
for (int a = 0; a < 100; a++)
{
//allocation part
for (int i = 0; i < nof; i++)
{
v1v2[i].list = (VPTYPE **)malloc(20 * sizeof(*v1v2[i].list));
for (int i2 = 0; i2 < 10; i2++)
{
VPTYPE *v = (VPTYPE *)malloc(sizeof(*v));
v->v1 = 1;
v->v2 = 2;
push(v1v2[i], v);
}
}
// free memory part
for (int i = 0; i < nof; i++)
{
for (int i2 = 0; i2 < (v1v2[i].last); i2++)
{
free(v1v2[i].list[i2]);
}
free(v1v2[i].list);
v1v2[i].list = 0;
v1v2[i].last = 0;
}
}
free(v1v2);
return 0;
}
Более простой рабочий код
В этом коде используется на один уровень косвенности меньше - и, следовательно, на один уровень распределения памяти - компилируется и работает одинаково чисто.
#include <stdlib.h>
#include <stdio.h>
#define push(s, ele) ((s).list[((s).last)++] = (ele))
typedef struct vp
{
short v1;
short v2;
} VPTYPE;
typedef struct VPLIST
{
int last;
VPTYPE *list;
} VPLISTTYPE;
enum { nof = 2 };
int main(void)
{
VPLISTTYPE *v1v2 = (VPLISTTYPE *)malloc(sizeof(*v1v2) * nof);
for (int i = 0; i < nof; i++)
v1v2[i].last = 0;
for (int a = 0; a < 100; a++)
{
//allocation part
for (int i = 0; i < nof; i++)
{
v1v2[i].list = (VPTYPE *)malloc(20 * sizeof(*v1v2[i].list));
for (int i2 = 0; i2 < 10; i2++)
{
VPTYPE v;
v.v1 = 1;
v.v2 = 2;
push(v1v2[i], v);
}
}
// free memory part
for (int i = 0; i < nof; i++)
{
free(v1v2[i].list);
v1v2[i].list = 0;
v1v2[i].last = 0;
}
}
free(v1v2);
return 0;
}