(在 C++ 中)如果在类的构造函数new
中使用关键字定义它们,那么在不使用关键字的情况下实例化一个类会导致在堆栈上创建其内部变量,还是在堆上创建它们?new
换句话说,如果我们有一个包含使用new
关键字在其构造函数内定义的变量(例如数组)的类或结构,将创建此类的实例而不使用new
导致在堆栈上创建内部数组,或者堆?
(在 C++ 中)如果在类的构造函数new
中使用关键字定义它们,那么在不使用关键字的情况下实例化一个类会导致在堆栈上创建其内部变量,还是在堆上创建它们?new
换句话说,如果我们有一个包含使用new
关键字在其构造函数内定义的变量(例如数组)的类或结构,将创建此类的实例而不使用new
导致在堆栈上创建内部数组,或者堆?
运算符 new 在堆中分配内存,除非您使用placement new 运算符,您可以在其中自己指向对象使用的内存。
如果我们有一个包含使用 new 关键字在其构造函数中声明的变量(例如数组)的类或结构,将在不使用 new 的情况下创建此类的实例,从而导致在堆栈或堆上创建内部数组?
是的,即使您在堆栈上创建一个对象(不带new
关键字),如果在类构造函数中使用 new,它的内部数据也将在堆上分配(当放置 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;
// ...
}
印刷:
使用的堆
实际上,int
在免费存储中已分配(并删除)了 100 个。
如果您需要指定内存位置,您可以使用placement new:
char buf[1024];
string* p = new (buf) string("on stack"); // pointer is on stack,
// data on the stack
考虑以下代码并假设没有优化:
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)
会被分配,但这次是从堆中分配的。
在这int
两种情况下,在 Foo 的构造函数中创建的 都将存储在堆中。这将至少增加堆的大小sizeof(int)
。
此外
...还有另一个new
不一定涉及堆使用的选项,即通过重载运算符 new(和 delete!)来定制分配。
结论(编辑评论)
因此,即使使用 创建new
,对象也可以驻留
每个新选项返回的地址都可以存储在调用进程的地址空间(堆栈、堆或数据段)中的任何位置。
用 anew
创建的任何东西都是在堆上创建的。
在不使用的情况下实例化一个类new
将堆栈分配类对象。然而,它的数据成员可能会也可能不会根据它们的实例化方式进行堆栈分配。
顺便说一句,static
函数内的变量也是堆分配的;这就是他们能够在函数调用之间保持值的方式。