accessing variable length array after its memory should have been deallocated

102 Views Asked by At

I'm currently studying variable length array and automatic storage.

I have the following code that allocate memory for an variable length array myArray inside function vla, and return a pointer to the variable length array from the function.

#include <stdio.h>

int * vla(int n){
    int myArray[n];

    myArray[0] = 10;
    myArray[1] = 11;

    int * pointerToInt = myArray;
    return pointerToInt;
}

int main(void){

    int * pointerToInt = vla(10);

    printf("%d, %d", pointerToInt[0], pointerToInt[1]); // prints 10, 11

    return 0;
}

I thought that variable length array belong to the automatic storage class (i.e. the memory for the variable length array will be allocated when we enter the function containing the variable length array, and the memory is automatically deallocated after the function exit)

So according to this logic, the memory allocated to myArray variable length array is deallocated after we return from vla method, but how come I can still correctly access the first and second element of the variable length array?

Is this behavior defined? or it is undefined behaviour that just happen to work?

2

There are 2 best solutions below

0
Mohammad Azim On BEST ANSWER

myArray is a stack/auto variable created on the stack memory. Remember memory always exists. It is just owned by different pointers based on allocation and deallocation. The reason why you can still access same values is that the same piece of memory has not been assigned to another pointer and not been overwritten.

To evaluate it. Create another function that allocates same amount from stack but puts different values. Or add arguments in the same function and call it twice with different values. You will then see the difference.

#include <stdio.h>

int * vla(int n, int a, int b){
    int myArray[n];

    myArray[0] = a;
    myArray[1] = b;

    int * pointerToInt = myArray;
    return pointerToInt;
}

int main(void){

    int * pointerToInt = vla(10, 10, 11);
    vla(10, 20, 21); // over write stack

    printf("%d, %d", pointerToInt[0], pointerToInt[1]); // prints 20, 21

    return 0;
}

By the way returning stack memory from vla is not a good idea. Dynamic memory is allocated from heap using malloc family of functions.

0
Cyril P Joy On

You can still correctly access the first and second element of the variable length array because you are assigning base address of the myArray to pointerToInt. Auto variables have a life inside the block only, but in this program we are using pointer to access the data in the memory, as long as that part of stack is not allocated to any other program, we can access that part of stack. If that part of stack is allocated to some other process we will get segmentation fault as we are trying to access unauthorized memory