我对在堆上分配对象和在堆栈上分配的主题以及何时以及如何调用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也分配了它内部的指针.堆上没有任何内容,所以不要删除它.
让我们明星你可能不需要动态分配任何东西.
静态数组或向量将更好地工作.
但是,假设您正在将此作为学习练习.
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)
如果您分配了每个成员(如果您想使用它们,您应该这样做:
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调用.
Vector* v = Vector[100];
Run Code Online (Sandbox Code Playgroud)
这是错的.如果不编译.
除非成员是指针,否则它在对象内.
如果成员是指针,则必须单独分配.
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)