c - Valgrind detects memory leak despite the fact memory has been freed -


i have file "a", 2000 characters, char "a" only, no spaces.

then have code, runs trough loop, add buffer, reallocs if limit reached , on errors frees strbuffer variable.

#include <stdlib.h> #include <stdio.h> #include <string.h>  int main() {     int maxs = 200;     int numericexpression;     int strlength;       char *strbuffer;     strbuffer = malloc(sizeof(char)*maxs+1);         if(strbuffer == null)         {             printf("failed allocate requested memory!\n");             free(strbuffer);             strlength = sizeof(strbuffer);             printf("freed %d bytes of memory!\n", strlength);             exit(99);         }         else         {             numericexpression = sizeof(char)*maxs+1;             printf("alocated: %d bytes of memory.\n", numericexpression);         }      // while simulation      int fcv = -1;     int numex;       // file opening simulation     file* fd = fopen("a", "r");       int c;     while((c=fgetc(fd) != eof)) // condition make sure realloc once     {         fcv++;         strbuffer[fcv] = c;         if(fcv == (maxs))            {             printf("additional memory space required!\n");                   int strlensize = strlen(strbuffer);              numex = (sizeof(char)*(2*strlensize));               strbuffer = realloc(strbuffer, numex);              if(strbuffer == null)             {                 printf("failed allocate requested memory!\n");                 strlength = sizeof(strbuffer);                 free(strbuffer);                 printf("freed %d bytes of memory!\n", strlength);                 exit(99);             }             else             {                 maxs = numex;                 printf("reallocation successful!\n");                 printf("alocated: %d bytes of memory.\n", numex);             }          }      }     strlength = sizeof(strbuffer);     free(strbuffer);     printf("freed %d bytes of memory!\n", strlength); } 

problem tells me in end, freed 8 bytes of memory. suppose because sizeof(strbuffer) doesn't respond expected size. when use strlen(strbuffer) instead, free 2001 bytes.

i suppose problem of printing out amount of bytes freed. doing wrong. maybe i'm not able tell how many bytes free. try valgrind , tells me, don't free enough, there memory leaks. in every branch of program, free memory used strbuffer.

when run through valgrind ("valgrind ./realloc"), tells me this:

==780== memcheck, memory error detector ==780== copyright (c) 2002-2013, , gnu gpl'd, julian seward et al. ==780== using valgrind-3.10.0.svn , libvex; rerun -h copyright info ==780== command: ./realloc ==780==  alocated: 201 bytes of memory. additional memory space required! ==780== invalid read of size 1 ==780==    @ 0x4c2e0f4: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==780==    0x400846: main (in /home/dan/desktop/test_ifj/realloc) ==780==  address 0x51fd109 0 bytes after block of size 201 alloc'd ==780==    @ 0x4c2ab80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==780==    0x40078c: main (in /home/dan/desktop/test_ifj/realloc) ==780==  reallocation successful! alocated: 402 bytes of memory. ==780== invalid write of size 1 ==780==    @ 0x400823: main (in /home/dan/desktop/test_ifj/realloc) ==780==  address 0x51fd562 0 bytes after block of size 402 alloc'd ==780==    @ 0x4c2ce8e: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==780==    0x400866: main (in /home/dan/desktop/test_ifj/realloc) ==780==  additional memory space required! reallocation successful! alocated: 806 bytes of memory. additional memory space required! ==780== conditional jump or move depends on uninitialised value(s) ==780==    @ 0x4c2e0f8: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==780==    0x400846: main (in /home/dan/desktop/test_ifj/realloc) ==780==  reallocation successful! alocated: 804 bytes of memory. freed 8 bytes of memory! ==780==  ==780== heap summary: ==780==     in use @ exit: 568 bytes in 1 blocks ==780==   total heap usage: 5 allocs, 4 frees, 2,781 bytes allocated ==780==  ==780== leak summary: ==780==    lost: 0 bytes in 0 blocks ==780==    indirectly lost: 0 bytes in 0 blocks ==780==      possibly lost: 0 bytes in 0 blocks ==780==    still reachable: 568 bytes in 1 blocks ==780==         suppressed: 0 bytes in 0 blocks ==780== rerun --leak-check=full see details of leaked memory ==780==  ==780== counts of detected , suppressed errors, rerun with: -v ==780== use --track-origins=yes see uninitialised values come ==780== error summary: 1200 errors 3 contexts (suppressed: 0 0) 

how free memory have allocated? won't cause memory leaks? - doing wrong , there's better way it? thank help.

question update

i followed advises , got 3 errors in 1 context. how code looks now:

#include <stdlib.h> #include <stdio.h> #include <string.h>  int main() {     int maxs = 200;     int numericexpression;       char *strbuffer;     strbuffer = malloc((maxs+1));         if(strbuffer == null)         {             printf("failed allocate requested memory!\n");             printf("freed %d bytes of memory!\n", maxs);             exit(99);         }         else         {             numericexpression = sizeof(char)*maxs+1;             printf("alocated: %d bytes of memory.\n", numericexpression);         }      // while simulation      int fcv = -1;     int numex;       // file opening simulation     file* fd = fopen("a", "r");      if(fd == null)     {         printf("error opening file!\n");          if(strbuffer != null)         {free(strbuffer);}           exit(99);     }       int c;      char *tmpbuffer;     while((c=fgetc(fd)) != eof) // condition make sure realloc once     {         fcv++;         strbuffer[fcv] = c;          if(fcv == (maxs))            {             printf("additional memory space required!\n");                    numex = ((2*fcv));               tmpbuffer = realloc(strbuffer, numex);             if(!tmpbuffer)             {                 free(strbuffer);                 printf("realloc() failed!\n");                 exit(99);             }                    else             {                 strbuffer = tmpbuffer;             }                  if(strbuffer == null)             {                 printf("failed allocate requested memory!\n");                 printf("freed %d bytes of memory!\n", maxs); // questionable, think                 exit(99);             }             else             {                 maxs = numex;                 printf("reallocation successful!\n");                 printf("alocated: %d bytes of memory.\n", maxs);             }          }      }      free(strbuffer);fclose(fd); // added, still errors occur      printf("freed %d bytes of memory!\n", maxs); } 

and same valgrind call ("valgrind ./realloc") this:

==1213== invalid write of size 1 ==1213==    @ 0x4007fd: main (in /home/dan/desktop/test_ifj/realloc) ==1213==  address 0x51fd560 0 bytes after block of size 400 alloc'd ==1213==    @ 0x4c2ce8e: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==1213==    0x400831: main (in /home/dan/desktop/test_ifj/realloc) ==1213==  additional memory space required! reallocation successful! alocated: 800 bytes of memory. additional memory space required! reallocation successful! alocated: 1600 bytes of memory. additional memory space required! reallocation successful! alocated: 3200 bytes of memory. freed 3200 bytes of memory! ==1213==  ==1213== heap summary: ==1213==     in use @ exit: 568 bytes in 1 blocks ==1213==   total heap usage: 6 allocs, 5 frees, 6,769 bytes allocated ==1213==  ==1213== leak summary: ==1213==    lost: 0 bytes in 0 blocks ==1213==    indirectly lost: 0 bytes in 0 blocks ==1213==      possibly lost: 0 bytes in 0 blocks ==1213==    still reachable: 568 bytes in 1 blocks ==1213==         suppressed: 0 bytes in 0 blocks ==1213== rerun --leak-check=full see details of leaked memory ==1213==  ==1213== counts of detected , suppressed errors, rerun with: -v ==1213== error summary: 3 errors 1 contexts (suppressed: 0 0) 

any tips cause one?

this problem:

strbuffer = realloc(strbuffer, numex); 

if call realloc() fails, returns null pointer, not free original memory allocation.

you need check return value first, assign original pointer if successful:

char *tmpbuffer = realloc(strbuffer, numex); if (!tmpbuffer) {   free(strbuffer);   puts("realloc() failed");   exit(1); } else {   strbuffer = tmpbuffer; } 

there few other issues code, including:

  • if strbuffer null, there no point passing free().

  • sizeof() not runtime function, has no idea how memory allocated.

  • strbuffer = malloc(sizeof(char)*maxs+1); bit sloppy. think meant strbuffer = malloc(sizeof(char)*(maxs+1));, have put strbuffer = malloc(maxs+1); since sizeof(char) 1 definition.


Comments

Popular posts from this blog

ruby on rails - RuntimeError: Circular dependency detected while autoloading constant - ActiveAdmin.register Role -

c++ - OpenMP unpredictable overhead -

javascript - Wordpress slider, not displayed 100% width -