堆与堆栈分配

Che*_*ebz 10 c++

我对在堆上分配对象和在堆栈上分配的主题以及何时以及如何调用delete()有点困惑.

例如,我有类Vector.我想做一些这些.

我可以做到这一点

Vector** v = new Vector*[100]; //create an array of 100 pointers to 100 Vector objects
Run Code Online (Sandbox Code Playgroud)

据我所知,这将在堆上分配所有东西(除了指针地址)?所以为了释放记忆,我需要:

for (int i = 0; i < 100; ++i)
{
   delete(v[i]);
}
delete(v);
Run Code Online (Sandbox Code Playgroud)

要不就

delete(v);
Run Code Online (Sandbox Code Playgroud)

足够?

另一个例子:

Vector* v = Vector[100];
Run Code Online (Sandbox Code Playgroud)

在这种情况下发生了什么?分配在哪里发生?堆还是堆?我还需要打电话吗?

delete(v);
Run Code Online (Sandbox Code Playgroud)

但这不是全部问题,对不起长篇大论...

例:

class Vector
{
  int x, y, z;
}

Vector* v = new Vector();
Run Code Online (Sandbox Code Playgroud)

是否分配了x,y,z?堆还是堆?

或者这个怎​​么样:

class Vector2
{
   int items[10];
}

Vector2* v2 = new Vector2();
Run Code Online (Sandbox Code Playgroud)

项目[10]在哪里分配?如何删除v2?我需要自定义析构函数吗?

最后但并非最不重要的是这个怎么样:

class Vector3
{
   int* items;
}

Vector3 v3 = Vector3();
Run Code Online (Sandbox Code Playgroud)

项目指针存储在哪里?堆还是堆栈?我该如何删除?

谢谢,抱歉很长的问题.我已经很长时间没遇这个东西,并且无法在线找到任何完整的解释.

Pri*_*ime 13

我会从头开始......

Vector** v = new Vector*[100];
Run Code Online (Sandbox Code Playgroud)

在堆上为一个类型为Vector的对象分配一个100个指针的数组它返回一个指针 - 你可以用它来跟踪这个指针数组.

删除这个100点的数组:

delete[] v;
Run Code Online (Sandbox Code Playgroud)

(对于单个分配的对象,对于数组使用delete运算符)deletedelete[]

下一个案例(我假设你的意思是new Vector[100]:

Vector* v = new Vector[100];
Run Code Online (Sandbox Code Playgroud)

您在堆上分配了一个包含100个向量的数组,并获得了指向其起始位置的指针 - v.删除此数组:

delete[] v;
Run Code Online (Sandbox Code Playgroud)

下一个...

class Vector
{
  int x, y, z;
}

Vector* v = new Vector();
Run Code Online (Sandbox Code Playgroud)

这会在堆上分配一个Vector类对象,并为您提供一个跟踪它的指针.因为您在堆上分配了整个对象,所以x,y和z都在堆上分配.

删除它:

delete v;


class Vector2
{
   int items[10];
}

Vector2* v2 = new Vector2();
Run Code Online (Sandbox Code Playgroud)

这个有点棘手,但我要推理出来......

课程是蓝图.在以某种方式实例化类之前,您根本没有分配任何内存,在本例中是在堆上.因为类是蓝图,items所以Vector2在堆上创建类的对象之前无法分配.我认为我们可以合理地推断出这items是在堆上分配的.

删除v2:

delete v2;
Run Code Online (Sandbox Code Playgroud)

最后:

class Vector3
{
   int* items;
}

Vector3 v3 = Vector3();
Run Code Online (Sandbox Code Playgroud)

您在堆栈上分配了所有类Vector3,因此items也分配了它内部的指针.堆上没有任何内容,所以不要删除它.

  • 忘了模板.在开始考虑模板之前,需要正确理解您对动态内存的理解.模板是一种完整的子语言(首先需要了解主要语言). (2认同)

Mar*_*ork 9

让我们明星你可能不需要动态分配任何东西.
静态数组或向量将更好地工作.

但是,假设您正在将此作为学习练习.

1分配指针数组

Vector** v = new Vector*[100]; //create an array of 100 pointers to 100 Vector objects
                               //
                               // The above comment is misleading.
                               // The 100 pointers have not been initialized.
Run Code Online (Sandbox Code Playgroud)

这分配了一个存储区域,其中有100个指针的空间(对于Vector(注意它们是未初始化的,即每个指针是随机的)).要删除它,您需要执行以下操作:

delete [] v;
Run Code Online (Sandbox Code Playgroud)

2分配阵列的成员

如果您分配了每个成员(如果您想使用它们,您应该这样做:

for (int i = 0; i < 100; ++i)
{
   v[i] = new Vector;
}

// Code

for (int i = 0; i < 100; ++i)
{
   delete v[i];
}
Run Code Online (Sandbox Code Playgroud)

请注意,对于每次调用new,都应该有相应的delete调用.

3错误

Vector* v = Vector[100];
Run Code Online (Sandbox Code Playgroud)

这是错的.如果不编译.

4会员去哪里

除非成员是指针,否则它在对象内.
如果成员是指针,则必须单独分配.

class Vector
{
  int x, y, z;
}

Vector* v1 = new Vector();
Vector  v2 = Vector();      // Yes the = Vector() is required
Run Code Online (Sandbox Code Playgroud)

这里v1指向包含x/y/z的动态分配对象.
这里v2是包含x/y/z的对象

我知道人们会说这 = Vector();是不需要的或复制结构.两种都是真的,但都错过了重点.1)它是一个复制结构,但编译器总是足够智能删除它.2)需要使其等同于上面的行.差别在于没有它default-initialized(即没有初始化)成员是zero-initialized(因为Vector()只有编译器生成的构造函数).

那么阵列成员呢.
他们与其他成员没有什么不同.成员总是在对象内部分配.如果成员是一个指针,那么它就在对象内部,但它必须明确设置它指向的内容.

class Bob
{
    int   dataArray[10];
    int*   dataPtr;
};
Bob  b1 = Bob();
Bob* b2 = new Bob();

b1.dataArray[0] = 1;            // dataArray is inside the object.
                                // b1 is allocated locally

b1.dataPtr      = new int [10]; // dataPtr is inside the object.
                                // But what it points at must be seprotally defined.
                                // Note you must call delete [] for each new []
b1.dataPtr[5] = 2;

b2->dataArray[0] = 1;           // dataArray is inside the object.
                                // b2 is allocated dynamically

b2->dataPtr      = new int [10];// dataPtr is inside the object.
                                // But what it points at must be aseptically defined.
                                // Note you must call delete [] for each new []
b2->dataPtr[5] = 2;
Run Code Online (Sandbox Code Playgroud)