Remember, you need one free() call for each malloc() or calloc() 
call.  You are creating a 2-D array using a set of distinct 1-D arrays.  
occupancy_grid is an array of pointers to 1-D arrays.  You allocate 
occupancy_grid (and should release it at the end), then fill its entries 
with pointers to allocated memory.  To release it you would reverse the 
process, freeing each 1-D array and then releasing occupancy_grid:

   for(i = 0; i < map_size_real.px; i++)
     free(occupancy_grid[i]);
   free(occupancy_grid);

You don't release each individual element, because you didn't allocate 
individual elements.

calloc() assigns 0 to every byte of memory allocated.  This can save you 
many lines of code to assign values to all values in a record.  In your 
original test program you had a map_cell_vector structure with four 
fields.  To avoid reading uninitialized memory, you can either use 
calloc() to assign all bytes in a map_cell_vector structure to 0, or you 
could use malloc() and then ensure that every field is initialized:

   map_cell_vector *ptr = (map_cell_vector *) 
malloc(sizeof(map_cell_vector));
   ptr->px = some_calculation;
   ptr->py = another_calculation;
   ptr->distance = a_third_calculation;
   ptr->next = NULL;

Your test program did not always assign values to the "distance" or 
"next" fields.  Although you never used the "distance" field, you did 
reference the "next" field and so you risked trying to read memory that 
you had not allocated.


On 10/6/2010 2:14 PM, Claudio Carbone wrote:
> Thank you David for your answer.
> I admit it's tough to follow all these pointers, but thanks to your
> explanations I've been able to greatly reduce the number of errors in my
> application.
> At least I can now free almost all the memory I borrow!
> But I'm still left mulling about freeing arrays of standard types.
> I created a double array of ints this way:
>
> int **occupancy_grid;
>
> occupancy_grid = malloc (map_size_real.px * sizeof (int *));
>    for(i = 0; i<  map_size_real.px; i++) {
>      occupancy_grid[i]=malloc (map_size_real.py * sizeof (int));
>
> (and here I could point that I fail to understand the need for calloc when
> malloc does the exact same thing...)
> Anyway this way when I then attempt to free the single entries I have to do
> this
>
> for (i=0; i<  map_size_real.px; i++)
>     for (j=0; j<  map_size_real.py; j++)
>         free(&  occupancy_grid[i][j]);
> free(occupancy_grid);
>
> this is understandable as I have to tell free() the area of memory to free
> so I have to de-reference the pointer.
> but the output is this
> ==6665== Invalid free() / delete / delete[]
> ==6665==    at 0x4024B3A: free (vg_replace_malloc.c:366)
> ==6665==    by 0x804884B: main (pointers.c:60)
> ==6665==  Address 0x426635c is 0 bytes after a block of size 4 free'd
> ==6665==    at 0x4024B3A: free (vg_replace_malloc.c:366)
> ==6665==    by 0x804884B: main (pointers.c:60)
> ==6665==
> ==6665== Invalid free() / delete / delete[]
> ==6665==    at 0x4024B3A: free (vg_replace_malloc.c:366)
> ==6665==    by 0x804886C: main (pointers.c:61)
> ==6665==  Address 0x4266358 is 0 bytes inside a block of size 4 free'd
> ==6665==    at 0x4024B3A: free (vg_replace_malloc.c:366)
> ==6665==    by 0x804884B: main (pointers.c:60)
> ==6665==
> ==6665==
> ==6665== HEAP SUMMARY:
> ==6665==     in use at exit: 0 bytes in 0 blocks
> ==6665==   total heap usage: 112 allocs, 212 frees, 1,720 bytes allocated
>
> Lots more of frees then allocs, and errors in freeing which I can't
> understand.
> Probably it's the&occupancy_grid[i][j] which is wrong, but I do not
> understand what should be done as using
>
> free(occupancy_grid[i][j])
>
> gives these
>
> ==6798== Conditional jump or move depends on uninitialised value(s)
> ==6798==    at 0x4024AFA: free (vg_replace_malloc.c:366)
> ==6798==    by 0x804884D: main (pointers.c:60)
> ==6798==
> ==6798== Invalid read of size 4
> ==6798==    at 0x8048844: main (pointers.c:60)
> ==6798==  Address 0x426635c is 0 bytes after a block of size 4 alloc'd
> ==6798==    at 0x4024F20: malloc (vg_replace_malloc.c:236)
> ==6798==    by 0x8048731: main (pointers.c:29)
> ==6798==
> ==6798== Invalid free() / delete / delete[]
> ==6798==    at 0x4024B3A: free (vg_replace_malloc.c:366)
> ==6798==    by 0x804884D: main (pointers.c:60)
> ==6798==  Address 0x38 is not stack'd, malloc'd or (recently) free'd
> ==6798==
> ==6798==
> ==6798== HEAP SUMMARY:
> ==6798==     in use at exit: 0 bytes in 0 blocks
> ==6798==   total heap usage: 112 allocs, 132 frees, 1,720 bytes allocate
>
> And the conditional jump reported doesn't even exist (at least not that I
> can see at that line).
>
> I know I'm missing something.
> Thank you for the patience in helping me.
> I once took a course in ansi c, but it's been time a long time ago :p
>
> Regards
> Claudio Carbone
>
>
>
> source i'm using
>
>
> #include<stdlib.h>
> #include<stdio.h>
>
>
>
> typedef struct map_cell_vector {
>    int px;
>    int py;
>    float distance;
>    struct map_cell_vector *next;
> } map_cell_vector;
>
>
> void free_vector (map_cell_vector *ptr);
>
> int main (int argc, const char **argv) {
>    int i,j;
>    map_cell_vector **array = (map_cell_vector**) malloc (10 *
> sizeof(map_cell_vector*));
>    for (i=0;i<10;i++)
>      array[i]=malloc(sizeof(map_cell_vector));
>    int **array2;
>
>    array2=malloc (10 * sizeof (int*));
>    for (i=0;i<10;i++)
>      array2[i]=malloc(sizeof(int));
>
>    map_cell_vector *ptr4,*ptr5;
>    for (i=0;i<10;i++){
>      ptr4=array[i];
>      ptr4->px=0+(10*i);
>      ptr4->py=0+(10*i);
>      for (j=1;j<10;j++) {
>        ptr5=(map_cell_vector*)malloc(sizeof(map_cell_vector));
>        ptr4->next=ptr5;
>        ptr4=ptr5;
>        ptr4->px=j+(10*i);
>        ptr4->py=j+(10*i);
>
>
>      }
>    }
>
>    for (i=0; i<10; i++) {
>      free_vector(array[i]);
>      for (j=0; j<10; j++)
>        free(array2[i][j]);
>
>    }
>    for (i=0; i<10; i++)
>      free(array2[i]);
>    free(array2);
>    free(array);
>
> }
>
> void free_vector (map_cell_vector *ptr) {
>    if (ptr->next != NULL) {
>      free_vector(ptr->next);
>    }
>    free(ptr);
> }
>
>
> ------------------------------------------------------------------------------
> Beautiful is writing same markup. Internet Explorer 9 supports
> standards for HTML5, CSS3, SVG 1.1,  ECMAScript5, and DOM L2&  L3.
> Spend less time writing and  rewriting code and more time creating great
> experiences on the web. Be a part of the beta today.
> http://p.sf.net/sfu/beautyoftheweb
> _______________________________________________
> Valgrind-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/valgrind-users
>


-- 
     David Chapman         [email protected]
     Chapman Consulting -- San Jose, CA


------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1,  ECMAScript5, and DOM L2 & L3.
Spend less time writing and  rewriting code and more time creating great
experiences on the web. Be a part of the beta today.
http://p.sf.net/sfu/beautyoftheweb
_______________________________________________
Valgrind-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/valgrind-users

Reply via email to