valgrind output : Invalid free() when program is stopped - c

I would like to implement an application which is in charge of running several tasks in parallel.
Before adding real tasks, I tried to set the base but the program returns various error when executing by valgrind.
==4827== Thread 3:
==4827== Invalid free() / delete / delete[] / realloc()
==4827== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400E31: my_handler (in /home/test)
==4827== by 0x4E416F9: start_thread (pthread_create.c:333)
==4827== Address 0x5420070 is 48 bytes inside a block of size 96 free'd
==4827== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400E31: my_handler (in /home/test)
==4827== by 0x4E416F9: start_thread (pthread_create.c:333)
==4827== Block was alloc'd at
==4827== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400B75: main (in /home/test)
==4827==
==4827== Thread 1:
==4827== Invalid read of size 8
==4827== at 0x400CD3: main (in /home/test)
==4827== Address 0x5420068 is 40 bytes inside a block of size 96 free'd
==4827== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400E31: my_handler (in /home/test)
==4827== by 0x4E416F9: start_thread (pthread_create.c:333)
==4827== Block was alloc'd at
==4827== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400B75: main (in /home/test)
==4827==
==4827== Invalid read of size 8
==4827== at 0x400CFF: main (in /home/test)
==4827== Address 0x5420068 is 40 bytes inside a block of size 96 free'd
==4827== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400E31: my_handler (in /home/test)
==4827== by 0x4E416F9: start_thread (pthread_create.c:333)
==4827== Block was alloc'd at
==4827== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400B75: main (in /home/test)
==4827==
==4827== Invalid read of size 8
==4827== at 0x400D30: main (in /home/test)
==4827== Address 0x5420060 is 32 bytes inside a block of size 96 free'd
==4827== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400E31: my_handler (in /home/test)
==4827== by 0x4E416F9: start_thread (pthread_create.c:333)
==4827== Block was alloc'd at
==4827== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400B75: main (in /home/test)
==4827==
tstop
==4827== Invalid write of size 8
==4827== at 0x400D5B: main (in /home/test)
==4827== Address 0x5420068 is 40 bytes inside a block of size 96 free'd
==4827== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400E31: my_handler (in /home/test)
==4827== by 0x4E416F9: start_thread (pthread_create.c:333)
==4827== Block was alloc'd at
==4827== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400B75: main (in /home/test)
==4827==
tstop
==4827== Invalid free() / delete / delete[] / realloc()
==4827== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400D8C: main (in /home/test)
==4827== Address 0x5420040 is 0 bytes inside a block of size 96 free'd
==4827== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400E31: my_handler (in /home/test)
==4827== by 0x4E416F9: start_thread (pthread_create.c:333)
==4827== Block was alloc'd at
==4827== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400B75: main (in /home/test)
==4827==
==4827==
==4827== HEAP SUMMARY:
==4827== in use at exit: 1,614 bytes in 4 blocks
==4827== total heap usage: 9 allocs, 7 frees, 3,334 bytes allocated
==4827==
==4827== LEAK SUMMARY:
==4827== definitely lost: 0 bytes in 0 blocks
==4827== indirectly lost: 0 bytes in 0 blocks
==4827== possibly lost: 0 bytes in 0 blocks
==4827== still reachable: 1,614 bytes in 4 blocks
==4827== suppressed: 0 bytes in 0 blocks
I guess these errors are related to memory accessing already freed and invalid free().
However, I can not really understand how and why they occur.
typedef int (*init)();
typedef int (*launch)();
typedef int (*stop)();
typedef struct stTask stTask_t;
typedef struct stEngine stEngine_t;
struct stTask
{
char name[10];
init initTask;
launch launchTask;
stop stopTask;
pthread_t tId;
};
struct stEngine
{
int16_t NbTasks;
stTask_t* TaskThread;
};
static void sig_handler(int signo);
static int tinit(void);
static int tlaunch(void);
static int tstop(void);
static void* my_handler(void* params);
stTask_t array[] =
{
{"TEST", (init)tinit, (launch)tlaunch, (stop)tstop, 0},
{"TEST2", (init)tinit, (launch)tlaunch, (stop)tstop, 0}
};
int exitReq;
stEngine_t engine;
int main (int argc, char *argv[])
{
struct sigaction action;
int i;
exitReq = 0;
memset(&engine, 0, sizeof(stEngine_t));
engine.NbTasks = 2;
memset(&action, '\0', sizeof(action));
action.sa_handler = &sig_handler;
sigfillset(&action.sa_mask);
action.sa_flags = 0;
if ((sigaction(SIGTERM, &action, NULL) != 0) || (sigaction(SIGINT, &action, NULL) != 0)) {
exit(EXIT_FAILURE);
}
engine.TaskThread = malloc(engine.NbTasks * sizeof(stTask_t));
for (i = 0; i < engine.NbTasks; i++) {
engine.TaskThread[i] = array[i];
engine.TaskThread[i].initTask();
pthread_create(&engine.TaskThread[i].tId, NULL, my_handler, (void *) &engine.TaskThread[i]);
}
while (!exitReq) {
//... do stuff
sched_yield();
}
for (i = 0; i < engine.NbTasks; i++) {
(void)pthread_cancel(engine.TaskThread[i].tId);
pthread_join(engine.TaskThread[i].tId, NULL);
engine.TaskThread[i].stopTask();
engine.TaskThread[i].tId = 0;
}
free(engine.TaskThread);
memset(&engine, 0, sizeof(stEngine_t));
return 0;
}
static void sig_handler(int signo)
{
if (signo == SIGINT || signo == SIGTERM) {
exitReq = 1;
}
}
static void* my_handler(void* params)
{
stTask_t* ptask = (stTask_t*) params;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
while (!exitReq) {
ptask->launchTask();
pthread_testcancel();
}
free(ptask);
pthread_exit(NULL);
}
static int tinit(void)
{
fprintf(stdout, "%s\n", __func__);
return 0;
}
static int tlaunch(void)
{
fprintf(stdout, "%s\n", __func__);
return 0;
}
static int tstop(void)
{
fprintf(stdout, "%s\n", __func__);
return 0;
}
By adding a comment into the handling function: I got no error but several bytes are still allocated when the program is manually stopped.
//free(ptask);
I get no error but several bytes are still allocated when the program is manually stopped.
As required I pass the struc's address as last parameter of pthread_create, but I probably misunderstand something about the memory
==6017== HEAP SUMMARY:
==6017== in use at exit: 1,614 bytes in 4 blocks
==6017== total heap usage: 9 allocs, 5 frees, 3,334 bytes allocated
==6017==
==6017== LEAK SUMMARY:
==6017== definitely lost: 0 bytes in 0 blocks
==6017== indirectly lost: 0 bytes in 0 blocks
==6017== possibly lost: 0 bytes in 0 blocks
==6017== still reachable: 1,614 bytes in 4 blocks
==6017== suppressed: 0 bytes in 0 blocks
Could someone explain me why, in both cases, memory is not freed correctly ?

Related

Possible memory leak valgrind c

I have just started using valgrind and am not very good with pointers so what I essentially want to do is pass the snake_thread s[1] variable as reference to all the functions so that I don't have to free the memory in each of the functions individually.
==20== HEAP SUMMARY:
==20== in use at exit: 17,704 bytes in 65 blocks
==20== total heap usage: 75 allocs, 10 frees, 32,646 bytes allocated
==20==
==20== 56 bytes in 1 blocks are still reachable in loss record 1 of 8
==20== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==20== by 0x10A068: initialize (snake_map_test.c:249)
==20== by 0x1098C1: main (snake_map_test.c:126)
==20==
==20== 56 bytes in 1 blocks are still reachable in loss record 2 of 8
==20== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==20== by 0x10A089: initialize (snake_map_test.c:250)
==20== by 0x1098C1: main (snake_map_test.c:126)
==20==
==20== 160 bytes in 1 blocks are still reachable in loss record 3 of 8
==20== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==20== by 0x10B992: Read_args (snake_map_test.c:571)
==20== by 0x109887: main (snake_map_test.c:122)
==20==
==20== 272 bytes in 1 blocks are possibly lost in loss record 4 of 8
==20== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==20== by 0x40149CA: allocate_dtv (dl-tls.c:286)
==20== by 0x40149CA: _dl_allocate_tls (dl-tls.c:532)
==20== by 0x485C322: allocate_stack (allocatestack.c:622)
==20== by 0x485C322: pthread_create##GLIBC_2.2.5 (pthread_create.c:660)
==20== by 0x10972E: main (snake_map_test.c:111)
==20==
==20== 272 bytes in 1 blocks are possibly lost in loss record 5 of 8
==20== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==20== by 0x40149CA: allocate_dtv (dl-tls.c:286)
==20== by 0x40149CA: _dl_allocate_tls (dl-tls.c:532)
==20== by 0x485C322: allocate_stack (allocatestack.c:622)
==20== by 0x485C322: pthread_create##GLIBC_2.2.5 (pthread_create.c:660)
==20== by 0x1098F8: main (snake_map_test.c:130)
==20==
==20== 400 bytes in 20 blocks are still reachable in loss record 6 of 8
==20== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==20== by 0x10BA1C: Read_args (snake_map_test.c:575)
==20== by 0x109887: main (snake_map_test.c:122)
==20==
==20== 5,880 bytes in 1 blocks are still reachable in loss record 7 of 8
==20== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==20== by 0x10A048: initialize (snake_map_test.c:248)
==20== by 0x1098C1: main (snake_map_test.c:126)
==20==
==20== 10,608 bytes in 39 blocks are possibly lost in loss record 8 of 8
==20== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==20== by 0x40149CA: allocate_dtv (dl-tls.c:286)
==20== by 0x40149CA: _dl_allocate_tls (dl-tls.c:532)
==20== by 0x485C322: allocate_stack (allocatestack.c:622)
==20== by 0x485C322: pthread_create##GLIBC_2.2.5 (pthread_create.c:660)
==20== by 0x109DD4: run_snake_threads (snake_map_test.c:217)
==20== by 0x485B608: start_thread (pthread_create.c:477)
==20== by 0x4997292: clone (clone.S:95)
==20==
==20== LEAK SUMMARY:
==20== definitely lost: 0 bytes in 0 blocks
==20== indirectly lost: 0 bytes in 0 blocks
==20== possibly lost: 11,152 bytes in 41 blocks
==20== still reachable: 6,552 bytes in 24 blocks
==20== suppressed: 0 bytes in 0 blocks
==20==
==20== Use --track-origins=yes to see where uninitialised values come from
==20== For lists of detected and suppressed errors, rerun with: -s
==20== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0)
These are the relevant functions
void* update(void* arg)
{
snake* s=(snake*)arg;
if (GAMEOVER == false)
{
if (s->dir == LEFT)
s->headX--;
else if (s->dir == RIGHT)
s->headX++;
else if (s->dir == DOWN)
s->headY++;
else if (s->dir == UP)
s->headY--;
}
pthread_exit(0);
}
void* run_snake_threads(void* arg)
{
snake_thread* s = (snake_thread*)arg;
while (GAMEOVER == false)
{
pthread_testcancel(); //cancellation point
map_init(s,s->food);
if(print_flag==1)
print(s->map);
for (int i = 0; i < s->info->size; i++)
{
input(s->snake_list, &s->snake_list[i], s->map, s->info,&s->food[i]);
int err = pthread_create(&(s->pid[i]), NULL, update, (void*)&(s->snake_list[i]));
if (err != 0) ERR("Couldn't create thread");
spawn_food(&s->snake_list[i], s->map,s->food,s->info);
update_tail(&s->snake_list[i]);
set_gameover(&s->snake_list[i], s->map);
usleep(s->snake_list[i].sleep_time);
}
}
free(s->food);
free(s->pid);
free(s->snake_list);
pthread_exit(0);
}
void initialize(snake_thread* s,int argc,char** argv)
{
s->snake_list = calloc(s->info->size,sizeof(snake) );
s->pid = calloc(s->info->size, sizeof(pthread_t) );
s->food=calloc(s->info->size,sizeof(snake_food));
//does some stuff and passes s to other functions
}
void Read_args(int argc, char** argv,snake_thread* s)
{
int c;
if (argc > 1)
while ((c = getopt(argc, argv, "x:y:f:")) != -1)
switch (c)
{
case 'x':
s->info->width_provided = true;
s->map->width = atoi(optarg);
break;
case 'y':
s->info->height_provided = true;
s->map->height = atoi(optarg);
break;
case 'f':
s->info->file_name_provided = true;
strcpy(s->info->file,optarg);
break;
default:
usage(argv[0]);
break;
}
else usage(argv[0]);
if(!(s->info->file))
{
strcpy(s->info->file,getenv("$SNAKEFILE"));
if(!(s->info->file))
{
printf("Warning, No save file provided\n");
}
}
init_size(argc,s->info);
//if(argc>optind) ERR("optind err");
s->map->map_elem_pos = calloc(s->map->height,sizeof(char*));
if (s->map->map_elem_pos == NULL) ERR("Malloc error for elements of map");
for (int i = 0; i < s->map->height; i++)
s->map->map_elem_pos[i] = calloc(s->map->width,sizeof(char));
}
int main(int argc, char** argv)
{
pthread_t pid;
snake_thread s[1]
Read_args(argc, argv, s);
if (access(s->info->file, F_OK) != 0)
initialize(s,argc,argv);
int err = pthread_create(&s->pid2, NULL, run_snake_threads, (void*)s);
if (err) ERR("Couldn't create thread");
pthread_join(s->pid2, NULL);
}

C: pass to function an array of structure pointers to be reallocated dynamically each time

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
Here's one problem:
char **mitems;
// ... assuming there's a mitems = malloc(...) or similar here...
mlabels[j]->items=mitems;
free(mitems);
Here you have a a pointer, you make it point to some memory you allocate, you copy the pointer (so you have two pointers pointing to the same memory) and then you free the memory that both pointers are pointing to.
The free call makes not only mitems invalid, but also mlabels[j]->items.
I solved ... here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
typedef struct s_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;
free(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);
addit(&ml,"CFILE","Cnew","Copen","Csave","Cbackup","Cprint","Csetup","Cexit",NULL);
addit(&ml,"DFILE","Dnew","Dsave","Dbackup","Dexit",NULL);
addit(&ml,"EFILE","Enew","Eopen","Esave","Eprint","Eexit",NULL);
printf("\n**********CHECK: %s",ml[3]->title);
for (int i=0;ml[i]!=NULL ;i++ )
free(ml[i]);
fprintf(stdout,"\n\033[1;91m***END***\033[0m\n");
return 0;
}
#Some_programmer_dude, if not free mitems then there will be no more accessible memory allocated ...thank you all

Swapping 2 pointer array of char without using strcpy and must use assignment operator?

Hello i was given a task to fix this program that it generates no errors log generated by valgrind.
This is the recent code
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
char *tukar(){
char *a, *b, *c;
a = (char *) malloc(sizeof(char) * 50);
b = (char *) malloc(sizeof(char) * 50);
c = (char *) malloc(sizeof(char) * 50);
strcpy(a,"string a");
strcpy(b,"string b");
printf("\nBefore :\n");
printf("a = %s\n",a);
printf("b = %s\n",b);
c = b;
b = a;
a = c;
printf("\nAfter :\n");
printf("a = %s\n",a);
printf("b = %s\n",b);
free(a);
free(b);
return c;
}
int main(){
char *y = tukar();
printf("%s\n",y);
free(y);
getchar();
return 0;
}
The current errors prints out
==5300== Memcheck, a memory error detector
==5300== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==5300== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==5300== Command: ./aa
==5300== Parent PID: 5110
==5300==
==5300== Invalid read of size 1
==5300== at 0x4C30D22: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x4EAA931: puts (ioputs.c:35)
==5300== by 0x1088CB: main (atan.c:33)
==5300== Address 0x52010c0 is 0 bytes inside a block of size 50 free'd
==5300== at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x108897: tukar (atan.c:26)
==5300== by 0x1088BB: main (atan.c:32)
==5300== Block was alloc'd at
==5300== at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1087BF: tukar (atan.c:8)
==5300== by 0x1088BB: main (atan.c:32)
==5300==
==5300== Invalid read of size 1
==5300== at 0x4C30D34: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x4EAA931: puts (ioputs.c:35)
==5300== by 0x1088CB: main (atan.c:33)
==5300== Address 0x52010c1 is 1 bytes inside a block of size 50 free'd
==5300== at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x108897: tukar (atan.c:26)
==5300== by 0x1088BB: main (atan.c:32)
==5300== Block was alloc'd at
==5300== at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1087BF: tukar (atan.c:8)
==5300== by 0x1088BB: main (atan.c:32)
==5300==
==5300== Invalid read of size 1
==5300== at 0x4EB5145: _IO_file_xsputn##GLIBC_2.2.5 (fileops.c:1309)
==5300== by 0x4EAA9F2: puts (ioputs.c:40)
==5300== by 0x1088CB: main (atan.c:33)
==5300== Address 0x52010c7 is 7 bytes inside a block of size 50 free'd
==5300== at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x108897: tukar (atan.c:26)
==5300== by 0x1088BB: main (atan.c:32)
==5300== Block was alloc'd at
==5300== at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1087BF: tukar (atan.c:8)
==5300== by 0x1088BB: main (atan.c:32)
==5300==
==5300== Invalid read of size 1
==5300== at 0x4EB515C: _IO_file_xsputn##GLIBC_2.2.5 (fileops.c:1309)
==5300== by 0x4EAA9F2: puts (ioputs.c:40)
==5300== by 0x1088CB: main (atan.c:33)
==5300== Address 0x52010c6 is 6 bytes inside a block of size 50 free'd
==5300== at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x108897: tukar (atan.c:26)
==5300== by 0x1088BB: main (atan.c:32)
==5300== Block was alloc'd at
==5300== at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1087BF: tukar (atan.c:8)
==5300== by 0x1088BB: main (atan.c:32)
==5300==
==5300== Invalid read of size 1
==5300== at 0x4C35028: __GI_mempcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x4EB5079: _IO_file_xsputn##GLIBC_2.2.5 (fileops.c:1327)
==5300== by 0x4EAA9F2: puts (ioputs.c:40)
==5300== by 0x1088CB: main (atan.c:33)
==5300== Address 0x52010c7 is 7 bytes inside a block of size 50 free'd
==5300== at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x108897: tukar (atan.c:26)
==5300== by 0x1088BB: main (atan.c:32)
==5300== Block was alloc'd at
==5300== at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1087BF: tukar (atan.c:8)
==5300== by 0x1088BB: main (atan.c:32)
==5300==
==5300== Invalid read of size 1
==5300== at 0x4C35038: __GI_mempcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x4EB5079: _IO_file_xsputn##GLIBC_2.2.5 (fileops.c:1327)
==5300== by 0x4EAA9F2: puts (ioputs.c:40)
==5300== by 0x1088CB: main (atan.c:33)
==5300== Address 0x52010c5 is 5 bytes inside a block of size 50 free'd
==5300== at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x108897: tukar (atan.c:26)
==5300== by 0x1088BB: main (atan.c:32)
==5300== Block was alloc'd at
==5300== at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1087BF: tukar (atan.c:8)
==5300== by 0x1088BB: main (atan.c:32)
==5300==
==5300== Invalid free() / delete / delete[] / realloc()
==5300== at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1088D7: main (atan.c:34)
==5300== Address 0x52010c0 is 0 bytes inside a block of size 50 free'd
==5300== at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x108897: tukar (atan.c:26)
==5300== by 0x1088BB: main (atan.c:32)
==5300== Block was alloc'd at
==5300== at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1087BF: tukar (atan.c:8)
==5300== by 0x1088BB: main (atan.c:32)
==5300==
==5300==
==5300== HEAP SUMMARY:
==5300== in use at exit: 50 bytes in 1 blocks
==5300== total heap usage: 5 allocs, 5 frees, 2,198 bytes allocated
==5300==
==5300== 50 bytes in 1 blocks are definitely lost in loss record 1 of 1
==5300== at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1087CD: tukar (atan.c:9)
==5300== by 0x1088BB: main (atan.c:32)
==5300==
==5300== LEAK SUMMARY:
==5300== definitely lost: 50 bytes in 1 blocks
==5300== indirectly lost: 0 bytes in 0 blocks
==5300== possibly lost: 0 bytes in 0 blocks
==5300== still reachable: 0 bytes in 0 blocks
==5300== suppressed: 0 bytes in 0 blocks
==5300==
==5300== For counts of detected and suppressed errors, rerun with: -v
==5300== ERROR SUMMARY: 27 errors from 8 contexts (suppressed: 0 from 0)
i'm suspecting that these assignments
c = b;
b = a;
a = c;
creates the problem. However, my teacher says it cannot be changed or replaced with strcpy(). I'm thinking about replacing the pointer's address but the pointer has been declared malloc() in it.
Is there any way to modify the code without replacing the assignments?
PS : 'tukar' means swap.
Remove this:
c = (char *) malloc(sizeof(char) * 50);
you don't need to allocate a third buffer, you never use it and in fact overwrite it when doing the swap. Just let c be a temporary char *.
Also, the allocations can be simplified to:
a = malloc(50);
b = malloc(50);
since you don't need to cast, and sizeof (char) is always 1.
For completeness' sake you should also check that the allocations succeed, before relying on it.
Then as pointed out in a comment remove the return, since that makes no sense at all.
What your teacher is likely fishing for, is that those assignments you point out only change where the pointers point, they do not make a hard copy of the data. There's two blatant bugs:
Upon c = b; you get a memory leak as the memory which c pointed at is lost.
And then when you later free what b points at, you also free what c now points at.
One solution would be to never allocate any memory for c, assign c to point at the same memory as b and then don't free what b points at.
Just got back asking from the friend.. He said the return c isn't having a problem. He said also the same about c doesn't need to be malloc()-ed (thanks to unwind's reference)...and about free(a) causes memory leak to c (thanks to Lundin's reference).
free(a) causes c to be gone, which it's reference to b also affected. The revised program will be
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
char *tukar(){
char *a, *b, *c;
a = malloc(50);
b = malloc(50);
strcpy(a,"string a");
strcpy(b,"string b");
printf("\nBefore :\n");
printf("a = %s\n",a);
printf("b = %s\n",b);
c = b;
b = a;
a = c;
printf("\nAfter :\n");
printf("a = %s\n",a);
printf("b = %s\n",b);
free(b);
return c;
}
int main(){
char *y;
y=tukar();
printf("%s",y);
free(y);
getchar();
return 0;
}
while valgrind gives output
==2527== Memcheck, a memory error detector
==2527== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==2527== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==2527== Command: ./aa
==2527== Parent PID: 2159
==2527==
==2527==
==2527== HEAP SUMMARY:
==2527== in use at exit: 0 bytes in 0 blocks
==2527== total heap usage: 4 allocs, 4 frees, 2,148 bytes allocated
==2527==
==2527== All heap blocks were freed -- no leaks are possible
==2527==
==2527== For counts of detected and suppressed errors, rerun with: -v
==2527== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
that's the goal of modifying the program.

Invalid read/write of size 4 in Valgrind

I am currently looking into a C program to debug where Valgrind was reporting errors.
I've stripped out some of the code into a small project to test where I think the problem is and I believe I've pretty much replicated the problem.
Below is my main function
int main(int argc, char** argv) {
FILE *csvFile = NULL;
csvFile = fopen("test.txt", "wb");
int arraySize = 10;
int i = 0;
targetsStruct *targets;
targetSummaryResultStruct *targetSummaryResult;
targets = malloc(arraySize + 10 * sizeof(targets));
targetSummaryResult = malloc(arraySize + 10 * sizeof(targetSummaryResultStruct));
for (i = 0; i < arraySize; i++)
{
asprintf(&targets[i].target, "TargetStruct: %i", i);
targets[i].rowID = i;
}
for (i = 0; i < arraySize; i++)
{
asprintf(&targetSummaryResult[i].target, "Target: %s", targets[i].target);
free(targets[i].target);
printf("%s\n", targetSummaryResult[i].target);
targetSummaryResult[i].callAttempts = i * 10;
fprintf(csvFile, "%s = %i\n", targetSummaryResult[i].target, targetSummaryResult[i].callAttempts);
free(targetSummaryResult[i].target);
}
fclose(csvFile);
printf("Structure completed");
free(targetSummaryResult);
free(targets);
return (EXIT_SUCCESS);
}
I'm malloc'ing the memory on purpose to say its arraySize + 10. The reason for this is the program I am trying to debug allocates a lot more array elements than are actually needed so I'm testing if this is a potential problem so although the array is 10 elements bigger I'm actually only filling 0 to the arraySize and the next 10 are left.
Below is how my structures are defined
typedef struct TargetSummaryResultStruct
{
char * target;
int callAttempts;
} targetSummaryResultStruct;
typedef struct TargetsStruct
{
char * target;
int rowID;
} targetsStruct;
Below is my valgrind report:
==10244== HEAP SUMMARY:
==10244== in use at exit: 0 bytes in 0 blocks
==10244== total heap usage: 43 allocs, 43 frees, 2,892 bytes allocated
==10244==
==10244== All heap blocks were freed -- no leaks are possible
==10244==
==10244== ERROR SUMMARY: 20 errors from 5 contexts (suppressed: 12 from 8)
==10244==
==10244== 4 errors in context 1 of 5:
==10244== Invalid read of size 4
==10244== at 0x8048619: main (main.c:48)
==10244== Address 0x40181e8 is 48 bytes inside a block of size 50 alloc'd
==10244== at 0x40072D5: malloc (vg_replace_malloc.c:291)
==10244== by 0x804856D: main (main.c:35)
==10244==
==10244==
==10244== 4 errors in context 2 of 5:
==10244== Invalid read of size 4
==10244== at 0x80485EC: main (main.c:47)
==10244== Address 0x40181e8 is 48 bytes inside a block of size 50 alloc'd
==10244== at 0x40072D5: malloc (vg_replace_malloc.c:291)
==10244== by 0x804856D: main (main.c:35)
==10244==
==10244==
==10244== 4 errors in context 3 of 5:
==10244== Invalid write of size 4
==10244== at 0x80485C2: main (main.c:41)
==10244== Address 0x40181ec is 2 bytes after a block of size 50 alloc'd
==10244== at 0x40072D5: malloc (vg_replace_malloc.c:291)
==10244== by 0x804856D: main (main.c:35)
==10244==
==10244==
==10244== 4 errors in context 4 of 5:
==10244== Invalid read of size 4
==10244== at 0xAF770B: vasprintf (in /lib/libc-2.12.so)
==10244== by 0xAD956A: asprintf (in /lib/libc-2.12.so)
==10244== by 0x80485B2: main (main.c:40)
==10244== Address 0x40181e8 is 48 bytes inside a block of size 50 alloc'd
==10244== at 0x40072D5: malloc (vg_replace_malloc.c:291)
==10244== by 0x804856D: main (main.c:35)
==10244==
==10244==
==10244== 4 errors in context 5 of 5:
==10244== Invalid write of size 4
==10244== at 0xAF76DD: vasprintf (in /lib/libc-2.12.so)
==10244== by 0xAD956A: asprintf (in /lib/libc-2.12.so)
==10244== by 0x80485B2: main (main.c:40)
==10244== Address 0x40181e8 is 48 bytes inside a block of size 50 alloc'd
==10244== at 0x40072D5: malloc (vg_replace_malloc.c:291)
==10244== by 0x804856D: main (main.c:35)
==10244==
--10244--
--10244-- used_suppression: 12 U1004-ARM-_dl_relocate_object /usr/local/lib/valgrind/default.supp:1391
==10244==
==10244== ERROR SUMMARY: 20 errors from 5 contexts (suppressed: 12 from 8)
I'm not sure how to fix these errors, my understanding of the invalid reads is that I'm trying to access some memory that may have already been free'd but part of the memory wasn't free'd for some reason.
I am new to C.
There is an arithmetic precedence mistake. * evaluated before +, therefore you get a memory block with wrong size. Also at first malloc, you are allocating memory to hold pointer of targetsStruct not the struct itself.
targets = malloc((arraySize + 10) * sizeof(targetsStruct)); //change targets to targetsStruct
targetSummaryResult = malloc((arraySize + 10) * sizeof(targetSummaryResultStruct));
I think what you meant to do in your malloc is
targets = malloc((arraySize + 10) * sizeof *targets);
and similarly for other malloc's.
The sizes you pass to malloc are incorrect because you're doing sizeof on the wrong thing. You're doing sizeof on the pointer, which will result into the size of the pointer, not the thing it points to. I have no idea why you're adding "arraySize" to the size you're allocating, but the mallocs should look like this:
targets = malloc(arraySize * sizeof *targets);
targetSummaryResult = malloc(arraySize * sizeof *targetSummaryResultStruct);
These messages indicate that you are accessing the memory past the allocated size.
You have allocated 50 bytes, then access the 4 bytes at offset 48, which includes bytes 48, 49 (legal), and 50, 51 (outside the allocation).
Later on, you access bytes 52, 53, 54, 55, all of which are outside, and valgrind tells you that there are 2 bytes in between the end of the allocation and the start of your access.

Invalid read of size 8, Invalid write of size 8, C

I have a valgrind errors, and I dont know how to get rid of them:
==5685== Invalid read of size 8
==5685== at 0x4008A1: main (in /home/mazix/Desktop/tests/filenames)
==5685== Address 0x5207670 is 608 bytes inside a block of size 609 alloc'd
==5685== at 0x4C2CD7B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5685== by 0x40075E: getFilenames (in /home/mazix/Desktop/tests/filenames)
==5685== by 0x40083C: main (in /home/mazix/Desktop/tests/filenames)
==5685==
==5685== Invalid read of size 8
==5685== at 0x4008BB: main (in /home/mazix/Desktop/tests/filenames)
==5685== Address 0x5207670 is 608 bytes inside a block of size 609 alloc'd
==5685== at 0x4C2CD7B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5685== by 0x40075E: getFilenames (in /home/mazix/Desktop/tests/filenames)
==5685== by 0x40083C: main (in /home/mazix/Desktop/tests/filenames)
==5685==
==5685==
==5685== FILE DESCRIPTORS: 3 open at exit.
==5685== Open file descriptor 2: /dev/pts/1
==5685== <inherited from parent>
==5685==
==5685== Open file descriptor 1: /dev/pts/1
==5685== <inherited from parent>
==5685==
==5685== Open file descriptor 0: /dev/pts/1
==5685== <inherited from parent>
==5685==
==5685==
==5685== HEAP SUMMARY:
==5685== in use at exit: 0 bytes in 0 blocks
==5685== total heap usage: 231 allocs, 231 frees, 43,693 bytes allocated
==5685==
==5685== All heap blocks were freed -- no leaks are possible
==5685==
==5685== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 2 from 2)
==5685==
==5685== 1 errors in context 1 of 3:
==5685== Invalid read of size 8
==5685== at 0x4008BB: main (in /home/mazix/Desktop/tests/filenames)
==5685== Address 0x5207670 is 608 bytes inside a block of size 609 alloc'd
==5685== at 0x4C2CD7B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5685== by 0x40075E: getFilenames (in /home/mazix/Desktop/tests/filenames)
==5685== by 0x40083C: main (in /home/mazix/Desktop/tests/filenames)
==5685==
==5685==
==5685== 1 errors in context 2 of 3:
==5685== Invalid read of size 8
==5685== at 0x4008A1: main (in /home/mazix/Desktop/tests/filenames)
==5685== Address 0x5207670 is 608 bytes inside a block of size 609 alloc'd
==5685== at 0x4C2CD7B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5685== by 0x40075E: getFilenames (in /home/mazix/Desktop/tests/filenames)
==5685== by 0x40083C: main (in /home/mazix/Desktop/tests/filenames)
==5685==
==5685==
==5685== 1 errors in context 3 of 3:
==5685== Invalid write of size 8
==5685== at 0x400806: getFilenames (in /home/mazix/Desktop/tests/filenames)
==5685== by 0x40083C: main (in /home/mazix/Desktop/tests/filenames)
==5685== Address 0x5207670 is 608 bytes inside a block of size 609 alloc'd
==5685== at 0x4C2CD7B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5685== by 0x40075E: getFilenames (in /home/mazix/Desktop/tests/filenames)
==5685== by 0x40083C: main (in /home/mazix/Desktop/tests/filenames)
==5685==
--5685--
--5685-- used_suppression: 2 dl-hack3-cond-1
==5685==
==5685== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 2 from 2)
and my code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glob.h>
char **getFilenames()
{
char **filenames = NULL;
glob_t data;
unsigned int i;
switch( glob("./*.*", 0, NULL, &data ) )
{
case 0:
break;
case GLOB_NOSPACE:
printf( "Out of memory\n" );
break;
case GLOB_ABORTED:
printf( "Reading error\n" );
break;
case GLOB_NOMATCH:
printf( "No files found\n" );
break;
default:
break;
}
filenames = malloc(sizeof(char*)*(data.gl_pathc)+1);
for(i=0; i<data.gl_pathc; i++)
{
int len = strlen(data.gl_pathv[i]);
filenames[i] = malloc(sizeof(char*)*len);
strcpy(filenames[i], data.gl_pathv[i]);
}
filenames[i] = NULL;
globfree( &data );
return filenames;
}
int main( int argc, char *argv[] )
{
char **filenames = getFilenames();
unsigned int i = 0;
for(i=0; filenames[i] != NULL; i++)
{
printf("%s\n", filenames[i]);
free(filenames[i]);
}
free(filenames[i]);
free(filenames);
return 0;
}
You're allocating space for data.gl_pathc pointers + 1 byte, then you're using data.gl_pathc + 1 pointers (the last pointer being set by filenames[i] = NULL;
In other words, your allocation
filenames = malloc(sizeof(char*) * (data.gl_pathc) + 1);
should probably be allocating data.gl_pathc + 1 pointers instead;
filenames = malloc(sizeof(char*) * (data.gl_pathc + 1));

Resources