C++ 实例化没有'new'关键字的类会导致在堆栈或堆上创建其内部变量吗?
(在C++中)如果在类的构造函数中使用C++ 实例化没有'new'关键字的类会导致在堆栈或堆上创建其内部变量吗?,c++,class,memory-management,stack,heap,C++,Class,Memory Management,Stack,Heap,(在C++中)如果在类的构造函数中使用new关键字定义内部变量,则在不使用new关键字的情况下实例化类会导致在堆栈上创建其内部变量,还是会在堆上创建 换句话说,如果我们有一个类或结构,其中包含一个使用new关键字在其构造函数中定义的变量(例如数组),那么在不使用new的情况下创建该类的实例是否会导致在堆栈上创建内部数组,或者堆?任何使用新建创建的内容都在堆上创建 不使用new实例化类将堆栈分配类对象。然而,它的数据成员可以根据实例化的方式进行堆栈分配,也可以不进行堆栈分配 顺便说一下,函数中的静
new
关键字定义内部变量,则在不使用new
关键字的情况下实例化类会导致在堆栈上创建其内部变量,还是会在堆上创建
换句话说,如果我们有一个类或结构,其中包含一个使用
new
关键字在其构造函数中定义的变量(例如数组),那么在不使用new
的情况下创建该类的实例是否会导致在堆栈上创建内部数组,或者堆?任何使用新建
创建的内容都在堆上创建
不使用new
实例化类将堆栈分配类对象。然而,它的数据成员可以根据实例化的方式进行堆栈分配,也可以不进行堆栈分配
顺便说一下,函数中的
静态
变量也是堆分配的;这就是它们在函数调用之间保持值的方式。运算符new在堆中分配内存,除非您使用placement new运算符,您可以将对象使用的内存指向该运算符。请考虑以下代码,并假设没有优化:
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;
}
将在堆栈上分配一些_foo
。堆栈将至少增长sizeof(Foo)
(这将至少有足够的空间来存储指向整数的指针(sizeof(int*)
)
由于使用了new
,堆中存储了some\u other\u foo
。同样,至少会从堆中分配sizeof(foo)
在这两种情况下,在Foo的构造函数中创建的int
将存储在堆上。这将使堆的大小至少增加sizeof(int)
如果我们有一个包含变量的类或结构(一个
示例)在其构造函数中使用new关键字will声明
不使用新的原因创建此类的实例
要在堆栈或堆上创建的内部数组
是的,即使您在堆栈上创建了一个对象(不带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;
// ...
}
除了
- 普通新(在堆上分配)
- 放置新语法(已分配内存)
new
的另一个选项不一定涉及堆使用,这是通过重载操作符new(和delete!)进行的自定义分配
结论(编辑评论) 因此,即使使用
new
创建,对象也可以驻留
- 在堆上(这是的默认行为)
- 在其所在的现有内存块中(placement new语法)
- 如果用户愿意,也可以在其他任何地方使用(通过重载new)
这些新选项返回的地址可以存储在调用进程(堆栈、堆或数据段)的地址空间的任何地方。
静态变量不在堆上。它们是静态分配的(给定固定地址).初始化的静态的变量在数据段上,未初始化的变量在数据段上。bss@AlanStokes你是对的,static
变量在数据段中。@Alan Stokes,你当然是对的(因此是尊敬的+1)但我要说的是,它们不是堆栈分配的——这是一个常见的误解。不是所有用new创建的东西都是在堆上创建的;placement new:char buf[1024];string*p=new(buf)string(“hello”);你能不能更精确一点:指向对象的指针放在堆栈上,而不是对象本身。什么对象?我很精确:指针在堆栈上,数据在堆栈上。我认为,即使你在堆栈上创建对象,这也会产生误导。我指的是文本,而不是代码片段。@WolfP。我可能会重写答案,请给我一个提示,告诉我我需要什么即使你在堆栈上创建了一个对象,它的内部数据也会分配到堆上,如果使用new,并在第二个示例之前粘贴它,基本上就可以了。我认为核心消息应该更好地与备选方案的详细描述分开。可能重复@Suma我认为这肯定是错误的ot的副本。可能的打字错误:堆栈将增长,您肯定是指“堆(使用)增长”。@WolfP.,哇。修复。谢谢。我不相信有这样的事情。@AlanStokes那么这(上面第三点)只是一个误解?这会让我平静下来:)…@AlanStokes现在我删除了伪造的静态语法。指针当然可以存储在任何地方。
char buf[1024];
string* p = new (buf) string("on stack"); // pointer is on stack,
// data on the stack