我创建了一个A类并编写了以下函数foo()
class A
{
public:
int a;
};
A * foo()
{
A a1;
return &a1;
}
int main()
{
A * a2;
a2 = foo();
return 0;
}
编译器给了我一个警告,因为a1是一个局部变量,我从堆栈中返回它的地址(所以它的值可以不可预测地改变)。
现在我将foo()更改为以下
A * foo()
{
A a1;
A *a3;
a3 = &a1;
return a3;
}
现在编译器没有给出任何警告。这是因为a3是在堆上创建的吗?如果是这样,指针总是像这样在堆上创建。我以为堆只能通过new / malloc使用。
答案 0 :(得分:4)
现在编译器没有发出任何警告。
编译器没有给出任何警告,因为你添加了足够的复杂性来欺骗你的代码所做的分析。
您仍然返回一个指向局部变量的指针,并且在函数返回后您无法使用该指针。
答案 1 :(得分:1)
您的代码仍然无效。您的编译器只会发出非常糟糕的警告。
答案 2 :(得分:1)
不,这只是因为编译器不够聪明,无法理解a3指向堆栈中的a1。
你在做什么仍然是未定义的。最好传入一个变量并将其设置为:
void foo(A& a1)
{
a1.something = 1;
a1.somethingElse = 2;
}
或使用smart-pointers。
答案 3 :(得分:1)
编译器只关注一层间接深度的警告 - 第二个例子和第一个例子一样危险。
答案 4 :(得分:1)
你还在返回堆栈中分配的项目的地址(所以它仍然是错误的)。但是因为你添加了另一层间接,你已经阻止了编译器检测到并警告你。