2

So, I have a pointer which need to increase it's "length" until the user insert a negative number or "e". It starts with the length of "1", via a malloc() then I use into a do{...} while(...) loop the realloc() function to increase its lenght. Here's the code:

int *array = malloc (sizeof(int) * 1);
bool exit = false;
int lastIndex = 0, value;

do {
    printf ("Insert a positive number. Insert a negative number or \"e\" to exit:  ");

    int scanf_result = scanf("%i", &value);
    if (scanf_result) {
      if (value >= 0) {
        array[lastIndex] = value;
        lastIndex++;
        array = (int*) realloc (array, lastIndex * sizeof(int));
      } else {
        exit = true;
      }
    } else {
      exit = true;
    }
} while (!exit);

I can't figure out why after the 7th cicle it exit with the error realloc(): invalid next size.

Any idea? Thanks in advice for help.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • regarding: `int scanf_result = scanf("%i", &value); if (scanf_result)` the returned value from 'this' call to `scanf()` can return 0, 1, or EOF. So the `if()` statement is not valid. It should be: `if( scanf_result == 1 )` Any other returned value indicates an error occurred. – user3629249 Jan 16 '19 at 20:06
  • regarding: `array = (int*) realloc (array, lastIndex * sizeof(int));` 1) in C, the returned value from `malloc`, `calloc` and `realloc` has type `void*` which can be assigned to any pointer, Casting just clutters the code, making it more difficult to understand, debug, etc. 2) When calling `realloc()`, never assign the returned value directly to the target pointer. Rather assign to a 'temp' variable, then check (!=NULL) and if successful, then assign the target pointer from the temp pointer. Otherwise when `realloc()` fails the original pointer is lost, resulting in a memory leak – user3629249 Jan 16 '19 at 20:11
  • regarding: `printf ("Insert a positive number. Insert a negative number or \"e\" to exit: ");` which suggests to enter 'e'. That 'e' will never by input by the statement: `if (scanf_result) {` due to the format string: "%i". However, that may be handled correctly by the program. However, if the user enters (or ) depending on the OS, that will be seen as a valid input – user3629249 Jan 16 '19 at 20:19

2 Answers2

3

You're not reallocating enough memory:

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

On the first iteration of the loop, lastIndex is incremented from 0 to 1, then you run the above realloc call. Since lastIndex is 1, you still only have enough space for 1 element. As a result, you write past the end of allocated memory on the next iteration.

This invokes undefined behavior, which in your case manifests as appearing to work properly for the first 6 iterations and failing on the 7th. It could have just as easily crashed on the first or second iteration.

Add one to the size you're allocating:

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

Also, don't cast the return value of malloc/realloc.

dbush
  • 205,898
  • 23
  • 218
  • 273
0

Fix your realloc:

array = (int*) realloc (array, (lastIndex + 1) * sizeof(int))

You are allocating one item less than you need to.

grapes
  • 8,185
  • 1
  • 19
  • 31