1

Why doesn't this code cause segmentation fault ? I thought after function returns, the content of local variables will be deleted.

char* test(){
    char buffer[BUFSIZ] = "Hello";
    char* word = buffer;

    return word;
}

int* test2(){
    int x = 10;
    int *ptr = &x;

    return ptr;
}

int main() {
    char* str = test();
    printf("str : %s\n", str);

    int *ptr = test2();
    printf("ptr : %d\n", *ptr);

    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 3
    Undefined behavior means that anything can happen, it doesn't have to cause a visible error. – Barmar Jun 03 '22 at 21:36
  • print str again after the call to test2 - it will surely have changed – pm100 Jun 03 '22 at 21:37
  • The memory isn't deleted, it gets reused for something else. – Barmar Jun 03 '22 at 21:37
  • If I return **&x**, this causes segmentation fault. **x** has **automatic storage duration**, but also *ptr has **automatic storage duration**. What's the difference between them ? – SigmundFreud Jun 03 '22 at 21:53
  • `ptr` points to `x`, which dies/disappears when `test2` returns, so `ptr` doesn't point to valid memory and accessing it invokes undefined behavior. [This](https://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope/6445794#6445794) is c++ but exactly the same thing. – yano Jun 03 '22 at 22:00

2 Answers2

1

The program has undefined behavior because the variables with automatic storage duration declared in the functions are not alive after exiting the functions.

The program can output the expected result because the memory occupied by the variables was not yet overwritten.

If to change your program for example the following way

#include <stdio.h>

char* test(){
    char buffer[BUFSIZ] = "Hello";
    char* word = buffer;

    return word;
}

char* test1(){
    char buffer[BUFSIZ] = "Bye";
    char* word = buffer;

    return word;
}


int main( void ) {
    char* str = test();
    printf("str : %s\n", str);

    char* str1 = test1();
    printf("str1 : %s\n", str1);

    printf("str : %s\n", str);

    return 0;
}

then its output might look like

str : Hello
str1 : Bye
str : Bye

That is the call of the function test1 results in overwriting of the memory early occupied by the array pointed to by the pointer str.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

I thought after function returns, the content of local variables will be deleted.

C has no such rule. It has no “delete” operation.

When an object is created, memory is reserved for it. This just means arrangements are made that some particular memory is available to store the value of the object and nothing else will use that memory for anything else. In typical C implementations, some memory on the hardware stack is used for automatic objects (the objects of variables defined inside functions that are not static or thread-local).

When the lifetime of the object ends, as when a function returns, that memory is no longer reserved.

That is all the C standard guarantees: That the memory is no longer reserved. It does not guarantee that the memory is erased, that the memory is cleared, or that the memory is immediately reused for another purpose. It is like checking out of a hotel room: The moment you check out, the hotel housekeeping staff might rush into the room and clean it up, or they might leave it while doing other work.

The C standard does not define the behavior when you use memory that is no longer reserved. Further, if you have a pointer to an object, the C standard does not define the behavior if you use the value of the pointer after the lifetime of the object ends.

When the C standard does not define the behavior, it imposes no requirements on how the program behaves. If the program leaves the data in memory and fetches its value when you try to use it, that conforms to the C standard. If the program overwrites the memory as the function is exiting and the value of the object is gone, that also conforms to the C standard. Generally, the C environment will not manage things for you; it is your job to write code that complies with the rules.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312