Meme Account
Meme Account

Reputation: 23

Passing pointer to pointer for reallocation in function

I'm a beginner C programmer and have issues implementing an (ordered) dynamic array of structs. Before adding an element to the array, I want to check if it is full and double it's size in that case:

void insert_translation(dict_entry **dict, char *word, char *translation){
    if( dictionary_entries == dictionary_size ){
        dict_entry *temp_dict;
        temp_dict = realloc(&dict, (dictionary_size *= 2) * sizeof(dict_entry) );
        // printf("Increased dict size to %d\n", dictionary_size);
        // if(temp_dict == NULL){
        //     fprintf(stderr, "Out of memory during realloc()!\n");
        //     /*free(dict);
        //     exit(EXIT_OUT_OF_MEMORY);*/
        // }

        //free(dict);
        //*dict = temp_dict;
    }

    dictionary_entries++;
    printf("Inserted %s into dict - %d of %d filled.\n", word, dictionary_entries, dictionary_size);
}

I call the function from the main function like this:

dictionary_size = 2; //number of initial key-value pairs (translations)
dictionary_entries = 0;
dict_entry *dictionary = malloc(dictionary_size * sizeof(dict_entry));
[...]
insert_translation(&dictionary, "bla", "blub");

In my understanding, dictionary is a pointer to a space in memory. &dictionary is a pointer to the pointer, which I pass to the function. In the function, dict is said pointer to pointer, so &dict should be the pointer to the area in memory? However, when I try to compile, I get the following error message:

pointer being realloc'd was not allocated

Edit

I expanded the code sample to show more of the code in the main function.

Upvotes: 0

Views: 594

Answers (2)

Lundin
Lundin

Reputation: 213428

&dict -> *dict. You can simplify the code by using a return type, to avoid such bugs:

dict_entry* insert_translation(dict_entry* dict, char *word, char *translation)
{
  ...

  if( dictionary_entries == dictionary_size )
  {
    dictionary_size *= 2;

    dict_entry *tmp = realloc(dict, sizeof(dict_entry[dictionary_size]));
    if(tmp == NULL)
    {
      // error handling, free(dict) etc
    }
    else
    {
      dict = tmp;
    }
  }

  ...

  return dict;
}

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 310930

The problem is in this statement

temp_dict = realloc(&dict, (dictionary_size *= 2) * sizeof(dict_entry) );

The parameter dict has the type

dict_entry **dict

in the statement that reallocs the memory you have to use the value of the pointer *dic but you are uisng an expression &dict that has the type dict_entry ***.

Compare the type of the left side of the assignment

ict_entry *temp_dict

with the type of the reallocated pointer. They should be the same (except in C one of them can have the type void *)

So you need to write

temp_dict = realloc(*dict, (dictionary_size *= 2) * sizeof(dict_entry) );
                    ^^^^^

In C arguments are passed by value. If you want to change the original value of an argument you should to pass it by reference through a pointer to the argument. In the function you need to dereference the pointer that to change the object pointed to by the pointer.

Upvotes: 2

Related Questions