简体   繁体   中英

Difference between returning *ptr and &x in C++

I have a simple program say :

#include <iostream>
using namespace std;

int* foo(){
    int x=5;
    return &x;
}
int main() {
    int* p=foo();
    cout<<*p;
}

This program gives a warning for returning address of a local variable. If I try to run it, I get a Segmentation Fault. Absolutely fine till now.

Now here is another program :

#include <iostream>
using namespace std;

int* foo(){
    int x=5;
    int* ptr=&x;
    return ptr;
}
int main() {
    int* p=foo();
    cout<<*p;
}

In this case, there is no warning when I build it. Why?

Also, when i run it, there is no Segmentation fault.I get 5 as output. Why?

What makes the second program work perfectly whereas the first one fails?

In the first case, the compiler was not only detecting the illegal behavior - returning an address of a local variable - it also recognized that this is undefined behavior and simply optimized it away. So it returned an invalid pointer instead, on purpose.

In the second case the compiler didn't realize it's undefined behavior and kept it. You are still using a variable which has already been freed at this point, it's just that it works by chance as it hasn't been overwritten yet.

You need to understand how pointers and memory works. All of these cases are invalid and if they work it is because the heuristics of the compiler compiled it in just the right way. All local variables are declared on the stack and then they go out of scope (ie your function exits) that stack memory is automatically freed and will be overwritten when something new is written to the stack (this is why you get the seg-fault because the is has detected an invalid memory access of memory that belongs to something else). The reason the function works is because the place in memory where 5 is stored has not been overwritten yet.

If you would like to return a pointer you must use new to declare the int. This will declare it on the heap and the memory will only be freed when you do so manually. You must then use delete to free the memory to avoid a memory leak when you are done.

The only reason the compiler picks up one invalid case vs the other is because it is legal c code but that one it can tell your likely intention the other it cannot.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM