在堆栈/堆上创建对象?

以下代码在堆栈上创建一个对象:

The following code creates an object on the stack:

Object o;

在堆上创建对象时我们可以使用:

When creating an object on the heap we can use:

Object* o;

o = new Object();

而不是:

Object* o = new Object();

当我们将堆对象创建分成两行并在第二行(o = new object())调用构造函数时,这是否意味着在第一行(Object* o) 指针是在堆栈上创建的吗?那么 Object o 将对象放入堆栈,而 Object* o 将指向未来对象的指针放入堆栈?

When we split the heap object-creation over two lines and call the constructor on the second line (o = new object()), does this mean in the first line (Object* o) the pointer was created on the stack? So Object o puts the object on the stack, whereas Object* o puts the pointer to a future object on the stack?

我的第二个问题涉及这两行代码是否在类之外调用.我最近阅读了(堆栈或堆中的 C 中的全局内存管理?)全局变量不包含在堆栈/堆中,但实际上是内存的另一部分?如果是这种情况,Object* o 是否会创建一个指针,该指针将位于内存的另一部分并指向堆对象?

My second question involves if the two lines of code were called outside of a class. I recently read (Global memory management in C in stack or heap?) that global variables are not contained on the stack/heap but actually another part of memory? If this is the case, would Object* o create a pointer which would sit in this other part of the memory and it points to the heap object?

推荐答案

实际上,这两个语句都没有提到堆或堆栈.代码

Actually, neither statement says anything about heap or stack. The code

Object o;

根据其上下文创建以下之一:

creates one of the following, depending on its context:

  • 具有自动存储功能的局部变量,
  • 命名空间或文件范围内的静态变量,
  • 指定另一个对象的子对象的成员变量.

这意味着存储位置由定义对象的上下文确定.另外,C++ 标准没有讨论栈vs 堆存储.相反,它谈论 存储持续时间,可以是 自动、动态、静态或线程本地.但是,大多数实现通过调用堆栈实现自动存储,通过堆实现动态存储.

This means that the storage location is determined by the context in which the object is defined. In addition, the C++ standard does not talk about stack vs heap storage. Instead, it talks about storage duration, which can be either automatic, dynamic, static or thread-local. However, most implementations implement automatic storage via the call stack, and dynamic storage via the heap.

因此在堆栈上创建了具有自动存储功能的局部变量.静态(和线程本地)对象通常分配在它们自己的内存区域中,既不在堆栈上,也不在堆上.并且在分配它们所属的对象的任何地方分配成员变量.它们有其包含对象的存储期限.

Local variables, which have automatic storage, are thus created on the stack. Static (and thread-local) objects are generally allocated in their own memory regions, neither on the stack nor on the heap. And member variables are allocated wherever the object they belong to is allocated. They have their containing object’s storage duration.

用一个例子来说明这一点:

To illustrate this with an example:

struct Foo {
    Object o;
};

Foo foo;

int main() {
    Foo f;
    Foo* p = new Foo;
    Foo* pf = &f;
}

现在对象Foo::o(即Foo类对象的子对象o)在哪里创建?这取决于:

Now where is the object Foo::o (that is, the subobject o of an object of class Foo) created? It depends:

  • foo.o 具有静态存储,因为 foo 具有静态存储,因此既不在堆栈上也不在堆上.
  • f.o 具有自动存储功能,因为 f 具有自动存储功能(= 它位于堆栈上).
  • p->o 具有动态存储,因为 *p 具有动态存储(= 它位于堆上).
  • pf->ofo 是同一个对象,因为 pf 指向 f.
  • foo.o has static storage because foo has static storage, and therefore lives neither on the stack nor on the heap.
  • f.o has automatic storage since f has automatic storage (= it lives on the stack).
  • p->o has dynamic storage since *p has dynamic storage (= it lives on the heap).
  • pf->o is the same object as f.o because pf points to f.

其实上面的ppf都有自动存储的.指针的存储与任何其他对象的存储没有区别,它由上下文决定.此外,初始化表达式对指针存储没有影响.

In fact, both p and pf in the above have automatic storage. A pointer’s storage is indistinguishable from any other object’s, it is determined by context. Furthermore, the initialising expression has no effect on the pointer storage.

pointee(=指针指向的东西)是完全不同的事情,它可以指代任何类型的存储:*p 是动态的,而 *pf 是自动的.

The pointee (= what the pointer points to) is a completely different matter, and could refer to any kind of storage: *p is dynamic, whereas *pf is automatic.

相关文章