I should dynamically allocate an array of pointers to structure, passing from time to time parameters for a single structure. sorry if I can not explain, here is the code
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
typedef struct _DROP_DOWN_MENU_LABELS
{
char *title;
char **items;
} MenuLabels;
MenuLabels ** ml_init(void)
{
MenuLabels **ml;
ml=(MenuLabels **)calloc(2,sizeof(MenuLabels*));
ml[1]=NULL;
return ml;
}
void addit(MenuLabels **mlabels, char *title, char *elems,...)
{
int j;
for (j=0; mlabels[j]!=NULL ; j++ );
printf("\n\nCHECK:MenuLabels has %d menu",j);
mlabels=(MenuLabels **)realloc(mlabels,(j+2)*sizeof(MenuLabels*));
mlabels[j]=(MenuLabels *)malloc(1*sizeof(MenuLabels));
mlabels[j+1]=NULL;
mlabels[j]->title=title;
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
int i=0;
char **mitems=NULL;
mitems=(char **)malloc(sizeof(char*));
mitems[i]=elems;
va_list argP;
va_start(argP, elems);
char *p;
for (i=1; ((p=va_arg(argP,char*)) !=NULL) ; i++ )
{
mitems=(char **)realloc(mitems,(i+1)*sizeof(char*));
mitems[i]=p;
}
if (!p)
{
mitems=(char **)realloc(mitems,(i+1)*sizeof(char*));
mitems[i]=NULL;
}
va_end(argP);
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
mlabels[j]->items=mitems;
}
int main()
{
MenuLabels **ml;
ml=ml_init();
addit(ml,"FILE","new","open","save","backup","print","setup","exit",NULL);
addit(ml,"AFILE","Anew","Asave","Abackup","Aexit",NULL);
addit(ml,"BFILE","Bnew","Bopen","Bsave","Bprint","Bexit",NULL);
free(ml);
fprintf(stdout,"\n\033[1;91m***END***\033[0m\n");
return 0;
}
starting the program seems to be executed without errors:
CHECK:MenuLabels has 0 menu
CHECK:MenuLabels has 1 menu
CHECK:MenuLabels has 2 menu
***END***
Process returned 0 (0x0) execution time : 0.001 s
Press ENTER to continue.
but checking with valgrind:
==5572== Memcheck, a memory error detector
==5572== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==5572== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==5572== Command: ./prove
==5572==
==5572== Invalid read of size 8
==5572== at 0x400812: addit (main.c:26)
==5572== by 0x400B27: main (main.c:75)
==5572== Address 0x5204040 is 0 bytes inside a block of size 16 free'd
==5572== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5572== by 0x400855: addit (main.c:29)
==5572== by 0x400AF1: main (main.c:74)
==5572== Block was alloc'd at
==5572== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5572== by 0x40075C: ml_init (main.c:15)
==5572== by 0x400AB0: main (main.c:73)
==5572==
CHECK:MenuLabels has 0 menu
==5572== Invalid free() / delete / delete[] / realloc()
==5572== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5572== by 0x400855: addit (main.c:29)
==5572== by 0x400B27: main (main.c:75)
==5572== Address 0x5204040 is 0 bytes inside a block of size 16 free'd
==5572== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5572== by 0x400855: addit (main.c:29)
==5572== by 0x400AF1: main (main.c:74)
==5572== Block was alloc'd at
==5572== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5572== by 0x40075C: ml_init (main.c:15)
==5572== by 0x400AB0: main (main.c:73)
==5572==
==5572== Invalid write of size 8
==5572== at 0x400882: addit (main.c:31)
==5572== by 0x400B27: main (main.c:75)
==5572== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==5572==
==5572==
==5572== Process terminating with default action of signal 11 (SIGSEGV)
==5572== Access not within mapped region at address 0x0
==5572== at 0x400882: addit (main.c:31)
==5572== by 0x400B27: main (main.c:75)
==5572== If you believe this happened as a result of a stack
==5572== overflow in your program's main thread (unlikely but
==5572== possible), you can try to increase the size of the
==5572== main thread stack using the --main-stacksize= flag.
==5572== The main thread stack size used in this run was 8388608.
CHECK:MenuLabels has 0 menu==5572==
==5572== HEAP SUMMARY:
==5572== in use at exit: 112 bytes in 4 blocks
==5572== total heap usage: 14 allocs, 10 frees, 1,392 bytes allocated
==5572==
==5572== 16 bytes in 1 blocks are definitely lost in loss record 2 of 4
==5572== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5572== by 0x400881: addit (main.c:31)
==5572== by 0x400B27: main (main.c:75)
==5572==
==5572== 96 (16 direct, 80 indirect) bytes in 1 blocks are definitely lost in loss record 4 of 4
==5572== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5572== by 0x400855: addit (main.c:29)
==5572== by 0x400AF1: main (main.c:74)
==5572==
==5572== LEAK SUMMARY:
==5572== definitely lost: 32 bytes in 2 blocks
==5572== indirectly lost: 80 bytes in 2 blocks
==5572== possibly lost: 0 bytes in 0 blocks
==5572== still reachable: 0 bytes in 0 blocks
==5572== suppressed: 0 bytes in 0 blocks
==5572==
==5572== For counts of detected and suppressed errors, rerun with: -v
==5572== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
./run_valgrind: riga 4: 5572 Errore di segmentazione (core dump creato) valgrind --leak-check=full --track-origins=yes --tool=memcheck ./prove
and in fact if I try to extract any value from ml at the end (eg ml[n]-> title) it goes into segmentation fault
what am I doing wrong? thank you all in advance
_DROP_DOWN_MENU_LABELSin your code) are reserved for the compiler and standard library in all scopes.