Yoskutik
Yoskutik

Reputation: 2089

C. The difference between realloc in double array and char array

I have to dynamically increase a length of double array. I know, how to do it with char array, so I tried this:

int main() {
    char * tmp = NULL;
    for (int i = 1; i <= 4; i++) {
        tmp = realloc(tmp, i * sizeof(char));
        tmp[i] = 'i';
    }
    puts("char OK");
    double * tmp1 = NULL;
    for (int i = 1; i <= 4; i++) {
        tmp1 = realloc(tmp1, i * sizeof(double));
        tmp1[i] = 0;
    }
    return 0;
}

The first array works fine. But the second one crushes with message realloc(): invalid next size.

These are my 2 questions:

  1. Why this way doesn't work in a double array?
  2. How to dynamically increase the size of array of doubles?

UPD: removed a typo

Upvotes: 0

Views: 88

Answers (1)

Sourav Ghosh
Sourav Ghosh

Reputation: 134376

TL;DR: Both the snippets are wrong, the first one appears to work because of undefined behavior.

To elaborate, the problem is with your indexing logic. C uses a 0-based indexing. So, inside the loop which is staring the iteration from value of i as 1, by using

 tmp[i] = .......

you're trying to access invalid memory, at this point, only access up to tmp[i-1] is valid.

You need to use tmp1[i-1] = 0;, and likewise.


That said,

  1. Always check for the success of the memory allocator functions before using the returned pointers.
  2. Never use the form

      pointer = realloc (pointer, ......)
    

    because, in case realloc call fails, you'll end up losing the original pointer, too.

    Quoting C11, chapter §7.22.3.5

    The realloc function returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated.

    and

    [....] If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged.

    • Always use a temporary pointer variable to store the return value of realloc(),
    • check for the success of the call [not-null return value] and
    • then assign it back to the original variable, if needed.

Upvotes: 9

Related Questions