7

假设我有这样的课程:

class Test
{
  int x;
  SomeClass s;
}

我像这样实例化它:

Test* t = new Test;

x 在栈上还是堆上?s呢?

4

6 回答 6

19
Test a;
Test *t = new Test;

a 及其所有成员都在堆栈中。

t 指向的对象及其所有成员都在堆上。

指针 t 在堆栈上。

于 2008-10-09T15:27:27.923 回答
10

每次使用 new(我们在这里说的是 C++)“实例化”一个对象/符号时,都会为这个对象分配一个新的内存区域。如果没有,它将被放在“本地”内存区域。

问题是我对“本地”内存区域没有标准定义。

一个例子

这意味着,例如:

struct A
{
   A()
   {
      c = new C() ;
   }

   B b ;
   C * c ;
}

void doSomething()
{
   A aa00 ;
   A * aa01 = new A() ;
}

对象 aa00 在堆栈上分配。

由于 aa00::b 根据 aa00 分配在“本地”内存上,因此 aa00::b 分配在新 aa00 指令分配的内存范围内。因此,aa00::b 也分配在堆栈上。

但是aa00::c是一个指针,用new分配的,所以aa00::c设计的对象是在堆上的。

现在,一个棘手的例子:aa01 是通过一个新的分配的,因此,在堆上。

在这种情况下,由于 aa01::b 根据 aa01 分配在“本地”内存上,因此 aa01::b 分配在新 aa01 指令分配的内存范围内。因此,aa01::b 位于堆上,“在”已为 aa01 分配的内存“内部”。

由于 aa01::c 是一个用 new 分配的指针,因此 aa01::c 设计的对象在堆上,在另一个内存范围内,而不是为 aa01 分配的内存范围。

结论

所以,游戏的重点是:
1 - 研究对象的“本地”内存是什么:堆堆栈?
2 - 如果对象是通过 new 分配的,那么它在这个本地内存之外,即它在堆上的其他地方
3 - 如果对象是“没有 new”分配的,那么它在本地内存内。
4 - 如果“本地”内存在堆栈上,那么没有 new 分配的对象也在堆栈上。
5 - 如果“本地”内存在堆上,那么没有 new 分配的对象也在堆上,但仍在本地内存中。

抱歉,我没有更好的词汇来表达这些概念。

于 2008-10-09T16:02:05.903 回答
6

由于您使用过new,所以它都在堆上,[或多或少]连续存储在t的内存区域中。

于 2008-10-09T15:27:03.227 回答
5

t 在堆栈上。*t 处的对象在堆上。它包含一个 int 和一个 SomeClass 对象,它们在一个单元中彼此相邻。

于 2008-10-09T15:27:31.977 回答
1

由于您使用的是 new,因此您将在堆上分配对象。因此,由 t 指向的每个测试成员也都在堆上。

于 2008-10-09T15:27:49.123 回答
1
class MyClass {
    int i;
    MyInnerClass m;
    MyInnerClass *p = new MyInnerClass();
}

MyClass a;
MyClass *b = new MyClass();

a 在堆栈上;它的成员 ai 和 am(包括 am 的任何成员)和 ap(指针,而不是它指向的对象)是它的一部分,因此也在堆栈上。

ap 指向的对象在堆上。

b 指向的对象在堆上,包括它的所有成员;bp指向的对象也是如此

于 2008-10-09T16:54:41.490 回答