当我们返回本地随机变量的引用时,我不太清楚我已经理解为什么会出现问题。所以,让我们说我们有这个例子。
int *myFunc() {
int phantom = 4;
return &phantom;
}
然后通常的论点是,当使用函数时,变量phantom
的内存在执行代码行int phantom = 4;
后不再可用,因此无法返回(至少这个是我迄今为止所理解的)。另一方面,对于该功能,
int myFunc() {
int phantom = 4;
return phantom;
}
整数变量phantom
的值将返回。 (我看到值的返回是变量phantom
的底层指针的解除引用)。
我在这里想念什么?为什么在第一种情况下存在编译错误,在第二种情况下,一切都有效?
答案 0 :(得分:2)
第一个不返回引用,它返回一个指针。一个指向局部变量的指针,一旦函数结束,它将超出范围,留下一个指向不再存在的变量的迷你指针。这就是为什么你得到编译器警告(通常不是实际错误)。
第二个代码复制该值。 return
语句完成后,函数内的局部变量永远不需要被引用或使用。
答案 1 :(得分:0)
你不要错过很多。只有在第一种情况下才会出现编译器错误。
[...]执行代码行int phantom = 4后,变量模型的内存不再可用;所以它不能被退回
不,它可以返回,编译器可能会发出警告,但是没有错误。但是,你不应该!!
顺便说一下,内存是可用的,但是在返回函数后(而不是在行int phantom = 4;
之后)访问它是未定义的行为。
在第二种情况下:
我看到值的返回是变量幻像的底层指针的解除引用
你在想这里太复杂了。从函数返回值可以通过使用指针来实现,但这是实现细节。你唯一需要关心的是返回的是值。所以在第二种情况下没有问题。
答案 2 :(得分:0)
第一种情况
int* myFunc()
{
int phantom = 4;
return &phantom; // you are returning the address of phantom
} // but phantom will not "exist" outside of myfunc
不起作用,因为变量phantom
是一个局部变量,它只在myfunc
执行期间存在。在那之后,它就消失了。
您正在返回一个变量的地址,这实际上将是#34;不存在"更多。
规则:永远不会返回指针或对局部变量的引用。
没关系:
int myFunc()
{
int phantom = 4;
return phantom; // you are returning by value;
// it doesn't matter where phantom "lives"
}
int main()
{
int x = myFunc(); // the value returned by myFunc will be copied to x
}
答案 3 :(得分:0)
我不太清楚我是否理解为什么会出现问题 我们返回一个局部随机变量的引用
因为如果您使用这样的函数,C ++标准说它是未定义的行为,并且您希望避免程序中未定义的行为。你的程序所做的应该由C ++语言的规则决定,而不是随机的。
请注意,您返回指针而不是引用。但在这两种情况下它都是未定义的行为。
然后通常的论点是当使用函数时,内存 变量
phantom
在执行后不再可用 代码行int phantom = 4;
因此无法返回(至少这一点 是我迄今为止所理解的。)
这是一个以实现为中心的观点,可能帮助您理解问题。
然而,区分程序的可观察行为和编译器产生该行为的内部技巧是很重要的。你甚至不知道是否有任何内存被变量占用。考虑" as-if"规则和编译器优化,即使行为已定义,整个函数也可能已被删除。这只是幕后可能发生的事情的一个例子。
但是,无论如何,它还是未定义的行为,所以任何事情都可能发生。
那么问题是,当你返回这样的指针然后尝试访问指针对象时,为什么C ++标准没有为这种情况定义行为?答案就是它没有意义。当函数返回时,局部变量phantom
命名的对象将终止它的生命。所以你会指向一个不再存在的东西,但它仍然是int*
,解除引用非nullptr
int*
应该产生int
。这是一个矛盾,而C ++标准并不打算解决这种毫无意义的情况。
请注意,这种观察是基于C ++语言规则,不是关于编译器实现问题。
为什么在第一种情况下存在编译错误,在第二种情况下 案例一切正常吗?
它肯定是一个警告,而不是错误,除非您的编译器选项使每个警告都变成错误。编译器不能拒绝代码,因为it's not ill-formed。
尽管如此,您的编译器仍尝试在第一种情况下提供帮助,因为它希望阻止您创建具有未定义行为的程序。
在第二种情况下,行为未定义。按值返回意味着副本由您要返回的对象组成。在销毁原件之前进行复制,然后调用者接收该副本。这不是没有意义的,也不是任何矛盾,所以它是安全和明确的行为。
在第一种情况下,按值返回对您没有帮助,因为虽然指针本身是被安全复制,但其内容最终会导致未定义的行为。
答案 4 :(得分:-1)
尝试返回指针并取消引用它以获取值。
#include <iostream>
using namespace std;
int *myFunc()
{
int number = 4;
int *phantom = &number;
return phantom;
}
int main()
{
cout << myFunc() << endl; //0x....
cout << *myFunc() << endl; //4
return 0;
}