关于c ++:实例化一个没有`new`关键字的类会导致它的内部变量在堆栈或堆上创建吗?

Will instantiating a class without the `new` keyword cause its internal variables to be created on the stack, or the heap?

(C++中)将实例化一个类,而不使用EDCOX1的0个关键字,因为如果在类的构造函数中使用EDCOX1的0个关键字来定义它们的内部变量,或者它们会在堆上创建,那么它的内部变量将被创建在堆栈上。

换句话说,如果我们有一个类或结构包含一个使用new关键字在其构造函数内定义的变量(例如数组),那么在不使用new的情况下创建这个类的实例会导致在堆栈或堆上创建内部数组吗?


if we have a class or struct that contains a variable (an array for
example) declared inside its constructor using the new keyword, will
creating an instance of this class without using new cause the
internal array to be created on the stack, or the heap?

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

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

类似地:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A{
public:
    A(){
        int* t = new int[100];
        std::cout<<"heap used
"
;
        delete t;
    }
};

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

    A a1;
    // ...
}

印刷品:

heap used

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

如果需要指定内存位置,可以使用新的放置:

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


考虑以下代码,不假设优化:

1
2
3
4
5
6
7
8
9
10
11
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*)的指针)。

由于使用了new,所以some_other_foo存储在堆中。同样,至少会分配sizeof(Foo),但这次是从堆中分配的。

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


operator new在堆中分配内存,除非使用placement new运算符,您可以将对象使用的内存指向该运算符。


除了

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

…还有另一个使用new的选项,它不一定涉及堆的使用,即通过重载new(和delete!)操作符来定制分配。.

结论(编辑评论)

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

  • 在堆上(这是默认行为)
  • 在已存在的内存中(放置新语法)
  • 如果用户愿意,也可以在其他任何地方(通过重载new)

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


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

不使用new实例化类将堆栈分配类对象。但是,它的数据成员可以或不可以根据它们的实例化方式进行堆栈分配。

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