【问题标题】:object created in function, is it saved on stack or on heap?在函数中创建的对象,它是保存在堆栈上还是堆上?
【发布时间】:2016-03-06 23:48:11
【问题描述】:

我专门使用 c++: 当我在函数中创建一个对象时,这个对象是保存在栈上还是堆上?

我问的原因是因为我需要保存指向对象的指针,并且可以创建对象的唯一位置是在函数内,所以如果我有一个指向该对象的指针并且方法完成,则指针可能是后指着垃圾。 --> 如果我将一个指向对象的指针添加到一个列表(它是该类的成员),然后方法完成,我可能会让列表中的元素指向垃圾。

再次如此 - 当在方法中创建对象时,它是保存在堆栈中(函数结束后它将无关紧要)还是保存在堆中(因此我可以指向它而不会引起任何问题..)?

示例:

class blah{ 
private:
    list<*blee> b;
public:
    void addBlee() {
        blee b;
        blee* bp = &b;
        list.push_front(bp);
    }
}

你可以忽略语法问题——以上只是为了理解概念和困境...

谢谢大家!

【问题讨论】:

    标签: c++ object pointers heap-memory stack-memory


    【解决方案1】:

    请记住以下几点:除非使用 new operatormalloc 变体在堆上显式分配,否则永远不会在堆中创建对象(在 C++ 中更准确地称为“动态存储”)。

    其他一切要么是堆栈/寄存器(在 C++ 中应称为“自动存储”),要么是静态分配的变量。静态分配变量的一个例子是程序中的全局变量,函数的局部变量,它们被声明为类的静态或静态数据成员。

    您还需要非常清楚地区分指针和对象本身。在以下单行中:

    void foo() {
        int* i = new int(42);
    }
    

    int 是动态分配的(在堆上),而指向分配的 int 的指针具有自动存储(堆栈或寄存器)。结果,一旦foo() 退出,指针就会被删除,但动态分配的对象仍然无法访问它。这称为经典内存泄漏

    【讨论】:

    • 只有一个小的更正:在你说“全局变量”的地方,也许它会被击中所说的静态分配——其中全局变量是可能的情况之一。
    【解决方案2】:

    堆是通常发生动态内存分配的段,因此当您显式为程序中的任何内容分配内存时,您已经从堆段中为其分配了内存。

    Obj yo = new Obj; //something like this.
    

    堆栈是存储自动变量的另一个部分,以及每次调用函数时保存的信息。

    就像我们声明时一样:

    *int* variable;
    

    它将在堆栈上,其有效性仅在特定函数退出之前有效,而堆上的变量、对象等将保留在那里直到 main() 完成。

    【讨论】:

    【解决方案3】:
    void addBlee() {
        blee b;              // this is created on the stack
        blee* bp = &b;
        list.push_front(bp); // this is a pointer to that object
    }  // after this brace b no longer exists, hence you have a dangling pointer
    

    改为这样做:

    list.push_front(new blee);  // this is created on the heap and
                                // therefore it's lifetime is until you call
                                // delete on it`
    

    【讨论】:

      猜你喜欢
      • 2010-11-06
      • 2016-12-27
      • 2021-06-19
      • 2011-02-03
      • 2011-10-07
      • 2013-12-09
      • 2013-10-26
      • 1970-01-01
      • 2011-01-04
      相关资源
      最近更新 更多