0

I am trying to fill a dynamically generated array using a for loop and make it bigger whenever needed using realloc(). However, when realloc is called several times on the memory, it replaces some values, especially the first and last few with seemingly random numbers.

This is the code I tested the said with:

#include <stdio.h>
#include <stdlib.h>

void fill(int * array, int size, int number_of_values) {
    for (int i = 0; i < number_of_values; i++) {
        if (i == size) {
            size *= 2;
            array = realloc(array, sizeof(int) * size);
        }

        array[i] = 100;
    }
}

int main() {
    int *array;
    int number_of_values = 21;
    int size = 5;

    array = malloc(sizeof(int) * size);

    fill(array, size, number_of_values);

    for (int i = 0; i < number_of_values; i++) {
        printf("%i ", array[i]);
    }
}

I tried reimplementing the code several times and looked at the array directly after assigning 100 to it, but all the values are assigned correctly at first and then change somehow. I also observed, that said behavior only seems to happen when there are more than 20 items assigned to the array in the loop.

The output of the program normally looks something like this:

10425976 10436440 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 134217736

Whereas when I set number_of_values to 20 and therefore only assign 20 values, the output looks like the following:

100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100

I also looked through some references of the realloc function, but as far as I'm concerned, I used it correctly.

Vntto
  • 25
  • 5
  • 4
    You discard the pointer returned by `realloc`. (You change `fill`'s `array`, but not `main`'s.) You are using a pointer that's no longer valid. – ikegami Apr 28 '20 at 19:29
  • Your print loop prints values from the array created by the very first call to malloc, not by realloc. – gudok Apr 28 '20 at 19:31
  • `array = realloc(array,...)` is a memory leak in case the `realloc` fails. You should always assign the return value of `realloc` to another pointer to check it. – Werner Henze Apr 28 '20 at 19:31
  • @ikegami Doesn't `array = realloc(array, sizeof(int) * size);` set `array` to the new pointer? – Vntto Apr 28 '20 at 19:31
  • 2
    Yes, that changes `fill`'s `array`. Not `main`'s, though. There are two variables named `array`, and you are only changing one of them. – ikegami Apr 28 '20 at 19:31
  • @Stephan, it does but only in `fill`. `main` still has the old pointer. – R Sahu Apr 28 '20 at 19:31
  • Thank you, returning the pointer helped. – Vntto Apr 28 '20 at 19:35

1 Answers1

0

The problem is that your function must return the newly allocated array.

int* fill(int * array, int size, int number_of_values) {
    ...
    return array;
}

int main() {
    ...
    array = fill(array, size, number_of_values);
    ,,,
}

Beginners generally get this wrong for a couple of reasons. They might think that because the two variables called array in main and in find both have the same name they are the same variable. This is not true.

The other reason is that sometimes beginners think that there is something special about pointers. If you change a pointer inside a function somehow it also changes the corresponding pointer in the calling function. I think this is a misunderstanding based on the fact that you can use a pointer to change the value being pointed at, but the pointer itself has the same rules as any other type of variable.

john
  • 71,156
  • 4
  • 49
  • 68