Search code examples
carraysdynamic-memory-allocationdynamic-arrays

Creating a dynamic array in C without specifying the maximum size


I am re-studying C right now and I have always been told that in C we have to define which maximum size would have an array so it can have enough space reserved in the memory. I mean this:

#include <stdlib.h> //Para función malloc

int main() {

   int *enteros = malloc( sizeof(int) * 10 ); //An array of 10 integers
   int i;
   for(i = 0; i < 100; i++) {
      enteros[i] = i*10;
      printf( "-> enteros[%d] = %d\n", i, i*10 );
   }
}

However, the following code works well (here I am not telling the max size, I just allocate enough memory for the pointer to int), and I just can't find an answer to what it's happening here.

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

int main() {
    int *enteros = malloc( sizeof(int) );
    int i;
    for(i = 0; i < 2000; i++) {
       *(enteros++) = i*10;
       printf( "-> enteros[%d] = %d\n", i, i*10 );
       enteros++;
   }
}

It seems that I just can manage dynamic arrays perfectly well, without having to reallocate memory for the array and being forced to introduce a starting size, however I feel that I'm missing something.


Solution

  • Yes, you can compile and run the code, but you may write data to addresses reserved by other variables.

    But this is just a source of the problem. The actual problem is that you are getting unexpected program behavior and run time errors extremely hard to find if you have large volume of code and with allocation issue inside. And it can be dramatic if happens on production. This cannot happen in most of other languages, but in C a developer is responsible.

    Try this code as an example:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        int *enteros = malloc( sizeof(int) );
        int *a = malloc( sizeof(int));
        int i;
        *a = 4; // value setup
        for(i = 0; i < 2000; i++) {
           *(enteros++) = i*10;
           printf( "-> enteros[%d] = %d\n", i, i*10 );
           enteros++;
       }
       printf( "a = %d\n", *a); // value changed!!!
    }
    

    Then comment out to double check:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        int *enteros = malloc( sizeof(int) );
        int *a = malloc( sizeof(int));
        int i;
        *a = 4;
        for(i = 0; i < 2000; i++) {
           // *(enteros++) = i*10;
           // printf( "-> enteros[%d] = %d\n", i, i*10 );
           enteros++;
       }
       printf( "a = %d\n", *a); // value did not change
    }
    

    https://repl.it/repls/SoggyOverdueFactors