use*_*112 50 c++ heap stack initialization
以下代码在堆栈上创建一个对象:
Object o;
Run Code Online (Sandbox Code Playgroud)
在堆上创建对象时,我们可以使用:
Object* o;
o = new Object();
Run Code Online (Sandbox Code Playgroud)
而不是:
Object* o = new Object();
Run Code Online (Sandbox Code Playgroud)
当我们将堆对象创建分成两行并在第二行(o = new object())上调用构造函数时,这是否意味着在第一行(Object* o)中指针是在堆栈上创建的?因此Object o将对象放在堆栈上,而Object* o将指针放在堆栈上的未来对象中?
我的第二个问题涉及两行代码是否在类之外调用.我最近读过(堆栈或堆中的C中的全局内存管理?)全局变量不包含在堆栈/堆中但实际上是内存的另一部分?如果是这种情况,会Object* o创建一个指针,它将位于内存的其他部分,并指向堆对象?
Kon*_*lph 92
实际上,两个语句都没有说明堆或堆栈:
Object o;
Run Code Online (Sandbox Code Playgroud)
创建一个具有自动存储的对象,这意味着存储位置由声明对象的上下文决定:如果代码在函数中,则恰好是调用堆栈.但是,该行也可以是一个类成员,或者如你所知,在一个函数/类之外.
为了说明这是不同的原因:
struct Foo {
Object o;
};
Foo* pf = new Foo();
Run Code Online (Sandbox Code Playgroud)
现在,对象pf->o是在堆上创建的,而不是在堆栈上创建的,即使(或者更确切地说,因为)它具有自动存储.
反过来,
Object* p;
Run Code Online (Sandbox Code Playgroud)
只需声明一个指针,仅此而已.的指针的存储是从任何其他对象的不可区分的:它具有自动存储.此外,初始化表达式对变量存储没有影响.
指针指向的是一个完全不同的问题.它可能是堆分配的对象(new例如使用),也可能指向另一个自动分配的对象.考虑:
Object o;
Object* p = &o;
Run Code Online (Sandbox Code Playgroud)
小智 11
C++提供了三种不同的方法来创建对象:
考虑你的情况,
Object* o;
o = new Object();
Run Code Online (Sandbox Code Playgroud)
和:
Object* o = new Object();
Run Code Online (Sandbox Code Playgroud)
两种形式都是一样的.这意味着在堆栈上创建指针变量o(假设您的变量不属于上面的3类),它指向堆中的内存,其中包含对象.
C++ 有自动变量 - 而不是堆栈变量。
自动变量意味着C++编译器自行处理内存分配/释放。C++ 可以自动处理任何类的对象 - 无论它是否具有动态分配的成员。这是通过 C++ 的强有力保证来实现的,当执行超出声明自动变量的范围时,将自动调用对象的析构函数。C++ 对象内部可以在构造函数中进行大量动态分配new,并且当将此类对象声明为自动变量时,将执行所有动态分配,然后在析构函数中释放。
C 中的堆栈变量不能动态分配。C 中的堆栈可以存储指针、固定数组或结构体 - 所有这些都具有固定大小,并且这些东西按线性顺序在内存中分配。当 C 程序释放堆栈变量时,它只是将堆栈指针向后移动,仅此而已。
尽管 C++ 程序可以使用堆栈内存段来存储原始类型、函数的参数或其他内容,但这都是由 C++ 编译器决定的,而不是由程序开发人员决定的。因此,将 C++ 自动变量和 C 堆栈变量等同起来在概念上是错误的。
两种形式相同,但有一个例外:临时地,(Object *)当创建和分配分开时,新的具有不确定的值。编译器可以将它们重新组合在一起,因为未定义的指针不是特别有用。这与全局变量无关(除非声明是全局的,在这种情况下,这两种形式都仍然适用)。