-1

I'm currently trying to write my 2D-Array in C and have one error from valgrind.

void free_2d_array(vocal **array)
{
  vocal *temp = array[0];
  int i = 0;

  while (array[i])
  {
    free(array[i++]);
  }

  if (array)
  {
    free(array);
  }
}

vocal **Set_2D_Array()
{
  vocal **temp_array = (vocal **)malloc(MALLOC_BUFFER * sizeof(vocal *));

  for (int i = 0; i < MALLOC_BUFFER; i++)
    temp_array[i] = NULL;

  for (int i = 0; i < MALLOC_BUFFER; i++)
  {
    temp_array[i] = (vocal *)malloc(MALLOC_BUFFER * sizeof(vocal));
    temp_array[i][0] = '\0';
  }

  return temp_array;
}

void Read_file(char *Path)
{
  vocal **coval_first_element = Set_2D_Array();

  for (int i = 0; i < 10; i++)
   insert(&coval_first_element[i], "Test");
  print_array(coval_first_element);
  free_2d_array(coval_first_element);
}

That's my code to free the allocated memory. And I don't know why i get this valgrind error.

==5470== Invalid read of size 8
==5470==    at 0x1088C7: free_2d_array (in /home/xanixx/Uni/ESP/A4/vocal)
==5470==    by 0x108721: Read_file (in /home/xanixx/Uni/ESP/A4/vocal)
==5470==    by 0x1086F4: main (in /home/xanixx/Uni/ESP/A4/vocal)
==5470==  Address 0x522d090 is 0 bytes after a block of size 80 alloc'd
==5470==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5470==    by 0x108737: Set_2D_Array (in /home/xanixx/Uni/ESP/A4/vocal)
==5470==    by 0x108711: Read_file (in /home/xanixx/Uni/ESP/A4/vocal)
==5470==    by 0x1086F4: main (in /home/xanixx/Uni/ESP/A4/vocal)

Has anyone of you a clue why this error occurred?

XaniXxable
  • 109
  • 1
  • 9
  • 1
    This isn't 2D arrays. See [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays). – Lundin Nov 14 '19 at 10:22
  • 1
    You sure you're not overwriting the allocated pointer in `insert(&coval_first_element[i], "Test");`? – Sourav Ghosh Nov 14 '19 at 10:23
  • @XaniXxable: You should compile your code with the `-g` option (if you use `gcc`), it will give you the numbre of the line in which the error occured. And more, you should use GDB and link it with valgrind, you will be able to see for which value of `i` the error occured (probably `MALLOC8BUFFER`, as pointed out by user312023) – Phantom Nov 14 '19 at 10:37

1 Answers1

0

I usually try to reduce number of mallocs. Two are enough.

void **myalloc(size_t sizex, size_t sizey, size_t elemsize)
{
    unsigned char **arr = NULL;

    if(sizey && sizex && elemsize)
    {
        arr = malloc(sizey * sizeof(void *));
        if(arr)
        {
            arr[0] = malloc(sizey * sizex * elemsize);
            if(arr[0])
            {
                for(size_t index = 1; index < sizey; index++)
                {
                    arr[index] = arr[0] + index * sizex *elemsize;
                }
                else
                {
                    free(arr);
                    arr = NULL;
                }
            }
        }
    }
    return arr;
}

void myfree(void **arr)
{
    if(arr)
    {
        if(*arr) free(*arr)
        free(arr);
    }
}
0___________
  • 60,014
  • 4
  • 34
  • 74