Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's wrong with realloc?

Tags:

c

Started to learn malloc.h in C. The idea was to create dynamic array. Here is the code:

#include <stdio.h>
#include <conio.h>
#include <malloc.h>

int main() {
    int *array = (int*)malloc(sizeof(int));
    int i, j, val;
    for (i = 0;; i++) {
        array = (int*)realloc(array, sizeof(int) + sizeof(*array));
        printf("Enter array[%d]=", i);
        scanf("%d", (array + i));
        if (*(array + i) == 0) break;
    }
    for (j = 0; j < i; j++) {
        printf("[%d] = %d\n", j, *(array + j));
    }
    getch();
    return 0;
}

The result is

Enter array[0]=1
Enter array[1]=2
Enter array[2]=3
Enter array[3]=4
Enter array[4]=5
Enter array[5]=6
Enter array[6]=7
Enter array[7]=8
Enter array[8]=9
Enter array[9]=10
Enter array[10]=0
[0] = 1
[1] = 2
[2] = 3
[3] = 4
[4] = 5
[5] = 6
[6] = 7
[7] = 8
[8] = 542979931
[9] = 875896893

Each time, >=8 values are random. I have just no idea why it happens so what's wrong?

like image 529
ovnia Avatar asked Mar 29 '13 12:03

ovnia


People also ask

What causes realloc to fail?

W.r.t failure realloc and malloc are almost equal. The only reason that realloc may fail additionally is that you give it a bad argument, that is memory that had not been allocated with malloc or realloc or that had previously been free d.

Does realloc destroy data?

Will I lose my data? No, the data will be copied for you into the new block that the returned p points at, before the old block is freed. This all happens before realloc returns, so the new p points to your data still.

Should I use realloc?

It's perfectly safe to use realloc . It is the way to reallocate memory in a C program. However you should always check the return value for an error condition.

What happens if realloc fails?

If size was equal to 0, either NULL or a pointer suitable to be passed to free() is returned. If realloc() fails the original block is left untouched; it is not freed or moved.


2 Answers

You undefined behavior in your code. I suppose, doing this:

array=(int*)realloc(array,sizeof(int)+sizeof(*array));

you expect, that sizeof(*array) will return you the size of the whole array, right? But that's not true. sizeof is computed at compile time and doing sizeof(*array) is actually the same as sizeof(int).

So, to make this array extensible, you need to have additional variable, holding the current number of elements and do something like:

array=(int*)realloc(array, sizeof(int) + current_size_of_array * sizeof( int ) );

where current_size_of_array will be incremented on each loop of the for, when you actually add one more element.

like image 108
Kiril Kirov Avatar answered Oct 10 '22 23:10

Kiril Kirov


sizeof(*array) does not tell you how large the array is. It tells you how many bytes an int occupies. So each call to realloc is only allocating memory for two int values. Change the realloc call to allocate sizeof(int) times the number of ints that you want.

like image 37
Pete Becker Avatar answered Oct 10 '22 22:10

Pete Becker