代码之家  ›  专栏  ›  技术社区  ›  Bruce

内存分配混乱

c++
  •  0
  • Bruce  · 技术社区  · 15 年前

    我创建了一个类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使用。

    5 回复  |  直到 15 年前
        1
  •  4
  •   James McNellis    15 年前

    现在编译器不会给出任何警告。

    编译器没有给出任何警告,因为您已经添加了足够的复杂性来愚弄它对代码所做的分析。

    您仍然返回指向局部变量的指针,并且在函数返回后不能使用该指针。

        2
  •  1
  •   Clark Gaebel    15 年前

    您的代码仍然无效。您的编译器只是给出了非常坏的警告。

        3
  •  1
  •   BlueRaja - Danny Pflughoeft    15 年前

    不,这只是因为编译器不够聪明,无法理解A3指向堆栈上的A1。

    你所做的还没有定义。最好传入一个变量,并按如下方式设置:

    void foo(A& a1)
    {
        a1.something = 1;
        a1.somethingElse = 2;
    }
    

    或使用 smart-pointers .

        4
  •  1
  •   Martin Beckett    15 年前

    编译器只关注一个级别的间接深度警告——第二个例子和第一个一样危险。

        5
  •  1
  •   Mark B    15 年前

    您仍然返回在堆栈上分配的项目的地址(所以仍然是错误的)。但是,由于添加了另一层间接寻址,您已经阻止了编译器检测到并警告您。