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;
}
CodePudding user response:
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
.
CodePudding user response:
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.