将实例化没有`new`关键字的类会导致其内部变量在堆栈或堆上创建吗?

时间:2013-11-15 08:07:03

标签: c++ class memory-management stack heap

(在C ++中)如果在类的构造函数中使用new关键字定义它们,那么在不使用new关键字的情况下实例化类会导致其内部变量在堆栈上创建,或者它们是在堆上创建的吗?

换句话说,如果我们有一个包含使用new关键字在其构造函数内定义的变量(例如数组)的类或结构,则将创建此类的实例而不使用{{1}导致在堆栈或堆上创建内部数组?

5 个答案:

答案 0 :(得分:3)

运算符new在堆中分配内存,除非您使用placement new运算符,您可以自己指定对象使用的内存。

答案 1 :(得分:3)

考虑以下代码并假设没有优化:

struct Foo {
    int* pointer_to_int;

    Foo() : pointer_to_int(new int) { }
    ~Foo() { delete pointer_to_int; }
}

void func() {
    Foo some_foo;
    Foo* some_other_foo = new Foo;
}

some_foo将在堆栈上分配。堆栈将增长至少sizeof(Foo)(这将至少有足够的空间来存储指向整数的指针(sizeof(int*))。

由于some_other_foo的使用,

new存储在堆上。同样,至少会分配sizeof(Foo),但这次是从堆中分配的。

在两种情况下,在Foo的构造函数中创建的int将存储在堆上。这将使堆的大小至少增加sizeof(int)

答案 2 :(得分:3)

  

如果我们有一个包含变量的类或结构(一个数组用于   例子)使用new关键字在其构造函数中声明   在不使用new的情况下创建此类的实例   要在堆栈上创建的内部数组,还是堆?

是的,即使您在堆栈上创建了一个对象(没有new关键字),如果在类construcor中使用new,它的内部数据将在堆上分配(当使用placement new分配数据时可能会有异常在堆栈上 - 我们稍后会看到它。常见的例子是分配一个数组:

int main() {
    int* t = new int[100];  // pointer is on stack, data on the heap
    //...
}

同样地:

class A{
public:
    A(){ 
        int* t = new int[100];
        std::cout<<"heap used\n";
        delete t;
    }
};

int main(int argc, char** argv) {

    A a1;
    // ...
}

打印:

  

堆使用

实际上,已经在免费商店中分配(和删除)了100个int


如果您需要指定内存位置,可以使用展示位置新

char buf[1024];
string* p = new (buf) string("on stack");  // pointer is on stack,
                                           // data on the stack

答案 3 :(得分:0)

除了

  • 普通新(在堆上分配)
  • 放置新语法(已分配内存)

...使用new的另一个选项不一定涉及堆使用,即重载运算符的自定义分配( 并删除! )。


结论(编辑评论)

因此,即使使用new创建,对象也可以驻留

    上(这是默认行为)
  • 放置在现有内存中(展示位置新语法)
  • 如果用户希望(重载新),
  • 也可以在任何其他地方使用

每个新选项返回的地址都可以存储在调用进程(堆栈,堆或数据段)的地址空间中的任何位置。

答案 4 :(得分:-1)

在堆上创建使用new创建的任何内容。

在不使用new的情况下实例化类将堆栈分配类对象。但是,它的数据成员可能会也可能不会根据实例化的方式进行堆栈分配。

顺便说一下,函数中的static变量也是堆分配的;这就是他们如何在函数调用之间保持值。