Search code examples
arrayscpointersmemorystack

Why can I still access array automatic allocated in function after return?


I tried to run this simple code and was expecting it to crash:

#include <stdio.h>

void setPtrOnTempData(char **ptr) {
    char str[] = "AAAA";
    *ptr = str;
}

int main() {
    char temp[] = "Paras";
    temp[3] = 'F';

    char *ptr = temp;
    ptr++;
    ptr[3] = 'F';
    printf("%s", ptr);  // prints "arFF"

    setPtrOnTempData(&ptr);

    ptr[0] = 'F';
    printf("%s", ptr);  // prints "FAAA"

    return 0;
}

The reasons why I thought so, if I'm not wrong:

  1. Elements of automatic allocated array are all allocated in stack, so after function return I lost control of it.
  2. Array variable is address of base element of this array in stack, so assignment of pointer passed as argument will point to that lost position in stack.

But result is that I still have access to some memory, where array was allocated and I'm still able to change data of this array.

Why is that so, and where my view is wrong? Thanks!!

UPD_1: I'm sorry for my inaccuracy, there was "statically" instead of "automatic" in the title at first.

UPD_2: I also tried to fill stack with some new data, for example, allocate in another function new array for 10 char elements, and call this function, thought maybe it will refresh data under ptr address, that was used by setPtrOnTempData earlier, but result is the same, data under ptr is not changed after it. Why is that so, if stack has grown and have been refreshed?


Solution

  • First, as a point of clarification, the array str in setPtrOnTempData is not statically allocated. Variables that are statically allocated, or more accurately those with static storage duration (i.e. with the static keyword or at file scope) have full program lifetime. What you have is a variable with automatic storage duration whose lifetime ends when setPtrOnTempData returns.

    When you access the memory of a variable whose lifetime has ended, as you've done here, it causes undefined behavior in your code.

    With undefined behavior, there is no guarantee what your code will do. It might crash, it might exhibit strange behavior, or (as in your case) it might appear to work properly. Also, the way undefined behavior manifests itself can change with a seemingly unrelated change to your code, such as adding an unused variable or a call to printf for debugging.

    Just because your code could crash doesn't mean it will.