繁体   English   中英

在C ++中返回* ptr和&x之间的区别

[英]Difference between returning *ptr and &x in C++

我有一个简单的程序说:

#include <iostream>
using namespace std;

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

该程序会警告您返回局部变量的地址。 如果尝试运行它,则会出现细分错误。 到目前为止还算不错。

现在这是另一个程序:

#include <iostream>
using namespace std;

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

在这种情况下,构建它时不会发出警告。 为什么?

另外,当我运行它时,没有细分错误。我得到5作为输出。 为什么?

是什么使第二个程序完美运行而第一个失败?

在第一种情况下,编译器不仅检测到非法行为-返回局部变量的地址-还认识到这是未定义的行为,并对其进行了简单的优化。 因此,它故意返回了无效的指针。

在第二种情况下,编译器没有意识到它是未定义的行为,而是保留了它。 您仍在使用一个已在此时释放的变量,只是由于它尚未被覆盖而偶然地起作用了。

您需要了解指针和内存的工作方式。 所有这些情况都是无效的,如果它们起作用,是因为编译器的试探法以正确的方式对其进行了编译。 所有局部变量都在堆栈上声明,然后超出范围(即,函数退出),即自动释放堆栈内存,并且在向堆栈中写入新内容时将覆盖它们(这就是为什么出现seg-fault的原因,因为则检测到对其他内存的无效内存访问)。 该功能起作用的原因是因为内存中存储5的位置尚未被覆盖。

如果要返回指针,则必须使用new声明int。 这将在堆上声明它,并且只有在您手动进行操作时才会释放内存。 然后,您必须使用Delete释放内存,以免在完成操作后发生内存泄漏。

编译器选择一个无效案例而不是另一个无效案例的唯一原因是因为它是合法的C代码,但它可以告诉您可能的意图而另一个则不能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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