Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When will stack memory be reallocated?

There is code like the following:

int fun(){

    char* pc = NULL;

    {
        char ac[100] = "addjfidsfsfds";
        pc = ac;
    }

    ...

    pc[0] = 'd';
    printf("%s\n", pc);
    ...
}

So, can I use pc safely after the scope of ac ends? Because I'm not sure whether the stack memory allocated for ac will be reallocated by the compiler for other usage or not.

like image 683
Yuan Wen Avatar asked Mar 30 '18 02:03

Yuan Wen


1 Answers

The defect in understanding you have has to do with the Storage Duration of Objects. Unless you are working with threads, you have three types to be concerned with, static, automatic, and allocated. By declaring char ac[100] = "addjfidsfsfds"; within the block and without the static storage-class specifier, the storage duration is automatic and its lifetime ends when execution of the bock ends. Attempting to access the value afterwards is Undefined Behavior.

The C-Standard lays this out in detail in section 6.2.4, e.g.

C11 - 6.2.4 Storage durations of objects

1 An object has a storage duration that determines its lifetime. There are four storage durations: static, thread, automatic, and allocated. Allocated storage is described in 7.22.3.

2 The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address,33) and retains its last-stored value throughout its lifetime.34) If an object is referred to outside of its lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.

3 An object whose identifier is declared without the storage-class specifier _Thread_local, and either with external or internal linkage or with the storage-class specifier static, has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.

( _Thread_local details omitted)

5 An object whose identifier is declared with no linkage and without the storage-class specifier static has automatic storage duration, as do some compound literals. The result of attempting to indirectly access an object with automatic storage duration from a thread other than the one with which the object is associated is implementation-defined.

6 For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. (Entering an enclosed block or calling a function suspends, but does not end, execution of the current block.) If the block is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate. If an initialization is specified for the object, it is performed each time the declaration or compound literal is reached in the execution of the block; otherwise, the value becomes indeterminate each time the declaration is reached.

7 For such an object that does have a variable length array type, its lifetime extends from the declaration of the object until execution of the program leaves the scope of the declaration.35) If the scope is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate.

If there is ever a question about whether accessing a value is allowed or not, consult the standard.

like image 152
David C. Rankin Avatar answered Oct 03 '22 15:10

David C. Rankin