1

I am trying to fully wrap my mind around malloc and memory allocation. I recently came across a situation that made me raise a brow.

When fiddling with arrays I was creating an array of arrays. Which in my mind would look something like this: [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], ...] When doing this I figured since I needed malloc to create the outer array. I also needed to call malloc for each inner array that I was creating. I quickly realized I get the same output when I skip this step which makes no sense to me.

Consider the following script.

int main(int argv, char* argc[]){

    // initialize outer array
    int* outer = malloc(5 * sizeof(int));

    int i, j;

    // for each slot in outer array
    // create a new array and assign it
    // to that slot.
    // NOT NEEDED.
    for(i = 0; i < 5; i++){
        int* inner = malloc(5 * sizeof(int));
        *(outer + i) = *inner;
    }
   // If I comment out the above four lines
   // the output remains the same.

    // assign to each slot in each inner array
    for(i = 0; i < 5; i++)
        for(j = 0; j < 5; j++)
            *(outer + i * 5 + j) = j;

    // print each element in each inner array
    for(i = 0; i < 5; i++){
        for(j = 0; j < 5; j++){
            printf(
                "%d ",
                *(outer + i * 5 + j)
            );
        }
        puts("");
    }
}

The output from this script is as follows:

0 1 2 3 4 
0 1 2 3 4 
0 1 2 3 4 
0 1 2 3 4 
0 1 2 3 4 

Which is what I expected. But when I comment out the first for loop in the script I get the same output. Why is this? Do I not need to allocate memory for the inner arrays? Clearly the answer is no but I'm trying to understand why that is.

marcusshep
  • 1,916
  • 2
  • 18
  • 31
  • What exactly is the idea behind this: `... = *inner;`? – alk Nov 18 '16 at 17:03
  • @alk for that index in the outer array, assign a new space of memory. – marcusshep Nov 18 '16 at 17:05
  • 2
    might be helpful even though the question is of c++ : http://stackoverflow.com/questions/4316736/using-unallocated-memory-without-error – Cherubim Nov 18 '16 at 17:07
  • 1
    Thanks @CherubimAnand – marcusshep Nov 18 '16 at 17:07
  • The initial `malloc` ( when compiled with clang ) is all that is used for the last two loops; the `malloc` within the for loop seems useless here... then again the compiler which is used can dictate the outcome. – l'L'l Nov 18 '16 at 17:31
  • @l'L'l I'm using gcc `Apple LLVM version 7.3.0 (clang-703.0.31)`. My assumption was that I needed to allocate space inside the outer array to make room for the inner arrays. – marcusshep Nov 18 '16 at 17:35
  • Both `Clang` and `GCC` seem to act much the same in this case; when viewing the [pseudo code](https://gist.github.com/anonymous/01d95ca55eed997c74d94b73c676ccdb#file-pseudo-malloc-c-L24-L27) it appears the first `malloc` sets everything up that follows. The flow graphs are also interesting showing [one](http://bl.ocks.org/anonymous/raw/012bb989a31db99703e5593b10b633b3) `malloc` and [two](http://bl.ocks.org/anonymous/raw/60234fafeae0c9163d63e9c55ab7dc37) `malloc` functions... (the second `malloc` is executed before the first). – l'L'l Nov 18 '16 at 18:16

1 Answers1

2

Short answer: Undefined behavior.

When you fail to allocate memory for the inner arrays, the pointers are uninitialized, so they point to some unspecified memory location.

With undefined behavior, your program may crash, it may behave in some unexpected manner or it may (as in your case) appear to work properly. A seemingly unrelated change such as adding unused variables can cause the programs behavior to change.

marcusshep
  • 1,916
  • 2
  • 18
  • 31
dbush
  • 205,898
  • 23
  • 218
  • 273