3

Background:

I created an array using calloc(), and everything was working great. Then I used realloc() to make the array larger. It seems to just create a new pointer with nothing in it and calling a runtime error when I try to access elements in the array.

My Code:

#include <stdio.h>

int main() {

  int *arr;

  for (int i = 0; i < 5; i++){
      if (i == 0) {
          if ((arr = (int *) calloc(1, sizeof(int))) == NULL) {
              printf("NO MORE SPACE TERMINATING PROGRAM");

              return NULL;
          }

      } else {
          int *tmp;

          if ((tmp = (int *)realloc(arr, 4*sizeof(int)) == NULL)){
              printf("NO MORE SPACE TERMINATING PROGRAM");
          }

          arr = tmp;
      }

      arr[i] = i;
  }
}

It throws a runtime error on the line arr[i]=i; when i = 1;

When I add a breakpoint 1 line above arr = temp; it shows that temp is completely blank.

Why is this happening?

--------Update----------------

Thanks for all of the help. Here is the working updated code:

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

int main(){
    int *arr = NULL;

    for (int i = 0; i < 5; i++){
        int *tmp;

        if ((tmp = realloc(arr, (i+1) * sizeof(int))) == NULL){
            printf("NO MORE SPACE TERMINATING PROGRAM");
        }

        arr = tmp;

        arr[i] = i;
    }

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

The output is: 01234

Thanks everyone for your help.

Joel
  • 1,585
  • 2
  • 10
  • 20
  • 5
    You don't `#include `, which is exactly why you shouldn't cast the result of `malloc`, `calloc` or `realloc`. Also `arr[4]` is one element beyond the 4 you `realloc` (3 is the maximum index you can address with a 4 element array). – Kninnug Nov 16 '15 at 00:30
  • 2
    Not related to your problem, but the `i == 0` case is redundant if you used `int *arr = NULL;` originally. It's safe to realloc a null pointer and it behaves the same as `malloc` in that case. – M.M Nov 16 '15 at 00:36
  • Also, as a matter of style `for (i = 0; ___; i++) { if (i == 0) {....}` would be more clearly written by just having the `{....}` block before the start of the loop – M.M Nov 16 '15 at 00:37

1 Answers1

5

Always heed the warnings. Doing so would show:

warning: assignment makes pointer from integer without a cast [enabled by default]
           if ((tmp = (int *)realloc(arr, 4*sizeof(int)) == NULL)){

Which tells you that the compiler is assigning an int to tmp. How is that possible? If you look carefully you will find that the parentheses are not correct. In effect it is assigining the result of realloc(arr, 4*sizeof(int)) == NULL to tmp. The correct code is below. Note where the parentheses are around the assignment.

if ((tmp = realloc(arr, 4*sizeof(int))) == NULL)

And you are missing #include <stdlib.h> for the definitions of calloc and realloc.

Update: As suggested by M.M and others, even if the above is fixed, the realloc is still not correct because it only allocates 4 elements whereas the for loop will access 5 elements. So need to change the 4 to 5 or i+1 for example. And even though it doesn't cause any functional problems, it's unnecessary to realloc on every loop after 0.

kaylum
  • 13,833
  • 2
  • 22
  • 31
  • It might also be good to mention that `4` is not enough; perhaps `(i+1)` would be better – M.M Nov 16 '15 at 00:38