0

In C I like to use anonymous arrays via void pointers, but when debugging some memory corruption happened. When I use valgrind it is spamming the mentioned message.

Honestly I have no idea what to try since this is a kinda exotic situation.

struct list_t {                                                                 
    void* first;                                                                
    void** elements;                                                            
    void* last;                                                                                                                                                                                                                                                                                                                

    unsigned int max_number_of_elements;                                        
    unsigned int number_of_elements;                                            

    unsigned int counter;                                                       
    void* element_current;                                                      
};
typedef struct list_t list;                                                     
typedef list* List; 
List list_create(                                                               

) {                                                                             
    List list = malloc(sizeof(list));                                                                          

    list->elements = (void**)malloc(sizeof(void*) * 16 );                                                                          

    ...                                             

    return list;                                                                
}

PS: Why was this marked as a duplicate since there is no clear answer on any even remotely related questions to this one?

mad_a_i
  • 23
  • 1
  • 5
  • 1
    You allocated the array of void pointer pointers but did you allocate the void pointers? – BugSquasher Apr 11 '19 at 02:25
  • The void pointers get filled later with different pointers. They are just placeholders for char pointers or int pointers or anything that needs to be pointed to. There is an insert function which keeps track of the already set pointers and reallocates if more memory is needed if the array is filled with pointers. – mad_a_i Apr 11 '19 at 02:29
  • An invalid write of size 8 would indicate your writing to a float or a large pointer. Are all your casts correct? – BugSquasher Apr 11 '19 at 02:31
  • I meant double not float – BugSquasher Apr 11 '19 at 02:32
  • No no the array get's only filled with pointers. For example: char* char_pointer = malloc(sizeof(char)); list->elements[2] = char_pointer; Since all pointers have a fixed size in C ( as far as I know ), the size of the memory it points to doesn't matter. The casting happens when I retrieve elements from that pointer array. – mad_a_i Apr 11 '19 at 02:37
  • Yes but if you're incorrectly casting an int to a double or something else, you can stomp memory. That's why void pointers are dangerous. That's why I asked if your casts are correct. There's not enough code to go on. – BugSquasher Apr 11 '19 at 02:44
  • The casts are all correct since I've been using that code for over two years. Valgrind giving out the error message over the malloc of the void pointer array. I'd provide the code but we are talking about multiple thousands of lines of code. – mad_a_i Apr 11 '19 at 02:46
  • list->elements = (void**)malloc(sizeof(void*) * 16 ); this is the line valgrind gives the invalid write size message about. – mad_a_i Apr 11 '19 at 02:51
  • `void*` is used to pass pointers around, say, to a functiona – sjsam Apr 11 '19 at 03:17
  • 1
    You will want to review: [Is it a good idea to **typedef** pointers?](http://stackoverflow.com/questions/750178/is-it-a-good-idea-to-typedef-pointers). – David C. Rankin Apr 11 '19 at 03:37
  • 1
    And do you know which `"list"` is using with `sizeof` in `List list = malloc(sizeof(list));`? Remember `typedef struct list_t list;`? So does `sizeof` take the `typedef` or pointer? Surely there is something other than `"list"` you can use to disambiguate. – David C. Rankin Apr 11 '19 at 03:43
  • 1
    Pointer typedefs claim another victim – M.M Apr 11 '19 at 03:45
  • 1
    What is worse you define the almost same names, differing in case only, to be 1) a struct, and 2) a pointer, c) a variable. – Antti Haapala -- Слава Україні Apr 11 '19 at 04:29
  • Well this isn't about my programming style. We are getting off track here. And yes I do know. I have an extremely strict naming scheme in my code which even got complimented by my professors. This is about the valgrind message I am getting. – mad_a_i Apr 12 '19 at 02:22
  • But to be fair the pointer named list in the list_create function is named wrong. It should be List this = malloc... . Stole that naming scheme from Java. These creator functions are in the hundreds and all work just fine except for this one which is one of my earlier ones. And also the only one where valgrind complains about the void pointer array and ONLY about the void pointer array – mad_a_i Apr 12 '19 at 02:24
  • Follow up: mad_a_i, do you see why `List list = malloc(sizeof(list));` is wrong? Use `List list = malloc(sizeof *list);` – chux - Reinstate Monica Apr 13 '19 at 20:15
  • Look at the typedefs at the bottom at the first chunk of code. Makes sense because List list = malloc(sizeof(list)) gets translated to struct list_t* list = malloc(sizeof(struct list_t)); – mad_a_i Apr 13 '19 at 20:22
  • And again: That line is not a problem and works fine since 5 years. It is the void pointer array allocation that doesn't work properly according to valgrind. – mad_a_i Apr 13 '19 at 20:24

1 Answers1

0

I see what's wrong. List list creates a list_t* and assigns it the memory allocated. However, sizeof(list) only allocated enough memory for a pointer. Your compiler is choosing the size of a list_t*, not the size of a list_t. Which means the line before the error is the problem. Change it to :

List list = (void*)malloc(sizeof(list_t));

And then it should work. The local pointer name is hiding the structure name and so chooses the wrong size to allocate.

BugSquasher
  • 335
  • 1
  • 13