C++ 如何释放动态结构数组的内存
作为一个从未处理过释放内存等问题的人,我的任务是创建一个结构的动态数组,并创建函数来添加或删除数组元素。删除时,我必须释放不再需要的内存 删除大小为3的数组的第二个元素时,我将第三个元素移动到第二个位置,然后删除最后一个元素。当删除最后一个时,我总是得到一个错误。。。有人能为我找到解决办法吗C++ 如何释放动态结构数组的内存,c++,arrays,memory,delete-operator,C++,Arrays,Memory,Delete Operator,作为一个从未处理过释放内存等问题的人,我的任务是创建一个结构的动态数组,并创建函数来添加或删除数组元素。删除时,我必须释放不再需要的内存 删除大小为3的数组的第二个元素时,我将第三个元素移动到第二个位置,然后删除最后一个元素。当删除最后一个时,我总是得到一个错误。。。有人能为我找到解决办法吗 struct myFriend { myFriend() { number=0; hobbys = new char*[10]; } int numb
struct myFriend {
myFriend() {
number=0;
hobbys = new char*[10];
}
int number;
char* name;
char** hobbys;
};
int main() {
myFriend* friendList = new myFriend[10];
myFriend* tempFriend = new myFriend;
tempFriend->number=1;
tempFriend->name = "ABC";
myFriend* tempFriend2 = new myFriend;
tempFriend2->number=2;
tempFriend->name = "XYZ";
myFriend* tempFriend3 = new myFriend;
tempFriend3->number=3;
tempFriend3->name = "123";
friendList[0] = *tempFriend;
friendList[1] = *tempFriend2;
friendList[2] = *tempFriend3;
friendList[1] = friendList[2]; //move 3rd element on 2nd position
delete &(friendList[2]); //and delete 3rd element to free memory
}
为什么要创建临时变量?甚至不需要它们 如果使用
std::vector
和std::string
,您面临的问题将自动消失:
std::vector<myFriend> friendList(10);
friendList[0]->number=1;
friendList[0]->name = "ABC";
friendList[1]->number=2;
friendList[1]->name = "XYZ";
friendList[2]->number=3;
friendList[2]->name = "123";
如果您执行以下任一操作,则它将是错误的,并将调用未定义的行为:
delete friends[2]; //wrong
delete &(friends[2]); //wrong
为什么要创建临时变量?甚至不需要它们 如果使用
std::vector
和std::string
,您面临的问题将自动消失:
std::vector<myFriend> friendList(10);
friendList[0]->number=1;
friendList[0]->name = "ABC";
friendList[1]->number=2;
friendList[1]->name = "XYZ";
friendList[2]->number=3;
friendList[2]->name = "123";
如果您执行以下任一操作,则它将是错误的,并将调用未定义的行为:
delete friends[2]; //wrong
delete &(friends[2]); //wrong
数组大小固定为10,因此不需要从中删除任何元素。但是您确实需要删除
好友列表[1]
中的名称
和霍布斯
元素(在覆盖之前)。这里有两个问题:
friendList[0]->name=“ABC”这里,“ABC”
是内存中某个以零结尾的常量字符串。不允许您删除它。所以你必须复制一份李>
无论何时分配爱好[i]
,您都要删除它。但是在你的代码中,你无法分辨它是否被分配。因此,必须将构造函数中的每个元素都设置为0,以便以后知道要删除哪些元素李>
删除这些元素的正确位置是myFriends的析构函数。数组大小固定为10,因此不需要从中删除任何元素。但是您确实需要删除
好友列表[1]
中的名称
和霍布斯
元素(在覆盖之前)。这里有两个问题:
friendList[0]->name=“ABC”这里,“ABC”
是内存中某个以零结尾的常量字符串。不允许您删除它。所以你必须复制一份李>
无论何时分配爱好[i]
,您都要删除它。但是在你的代码中,你无法分辨它是否被分配。因此,必须将构造函数中的每个元素都设置为0,以便以后知道要删除哪些元素李>
删除这些元素的正确位置是
myFriends
的析构函数。无法从new[]分配的数组中删除子集。
myFriend*friendList=newmyfriend[10]代码>
你有一个完整的数组
+------------------------------------------------------------------+
| friendList[0] | friendList[1] | ..... | friendList[9] |
+------------------------------------------------------------------+
您不能删除&(好友列表[2])
。
您可以从C++
获得10个元素的整个数组。
此数组从好友列表
(或&(好友列表[0])
)开始
operator delete
,其指针指向new
(即friendList
)返回的地址是有效的
仅限。无法从new[]分配的数组中删除子集。
myFriend*friendList=newmyfriend[10]代码>
你有一个完整的数组
+------------------------------------------------------------------+
| friendList[0] | friendList[1] | ..... | friendList[9] |
+------------------------------------------------------------------+
您不能删除&(好友列表[2])
。
您可以从C++
获得10个元素的整个数组。
此数组从好友列表
(或&(好友列表[0])
)开始
operator delete
,其指针指向new
(即friendList
)返回的地址是有效的
只有。问题的关键似乎是管理动态数组。主要的问题是他使用的是一个朋友列表数组。使用指向好友列表的指针数组:
struct myFriend {
myFriend() {
number=0;
hobbys = new char*[10];
}
int number;
char* name;
char** hobbys;
};
int main() {
myFriend** friendList = new myFriend*[10];
myFriend* tempFriend = new myFriend;
tempFriend->number=1;
tempFriend->name = "ABC";
myFriend* tempFriend2 = new myFriend;
tempFriend2->number=2;
tempFriend->name = "XYZ";
myFriend* tempFriend3 = new myFriend;
tempFriend3->number=3;
tempFriend3->name = "123";
friendList[0] = tempFriend;
friendList[1] = tempFriend2;
friendList[2] = tempFriend3;
friendList[1] = friendList[2]; //move 3rd element on 2nd position
delete friendList[2]; //and delete 3rd element to free memory
}
但其他人都是对的——关于“霍布斯”和“名字”的内存分配,存在着一些主要问题,需要分别进行分类。问题的关键似乎是管理一个动态数组。主要的问题是他使用的是一个朋友列表数组。使用指向好友列表的指针数组:
struct myFriend {
myFriend() {
number=0;
hobbys = new char*[10];
}
int number;
char* name;
char** hobbys;
};
int main() {
myFriend** friendList = new myFriend*[10];
myFriend* tempFriend = new myFriend;
tempFriend->number=1;
tempFriend->name = "ABC";
myFriend* tempFriend2 = new myFriend;
tempFriend2->number=2;
tempFriend->name = "XYZ";
myFriend* tempFriend3 = new myFriend;
tempFriend3->number=3;
tempFriend3->name = "123";
friendList[0] = tempFriend;
friendList[1] = tempFriend2;
friendList[2] = tempFriend3;
friendList[1] = friendList[2]; //move 3rd element on 2nd position
delete friendList[2]; //and delete 3rd element to free memory
}
但其他人都是对的——关于“hobbys”和“name”的内存分配有一些主要问题,需要分别加以解决。要做作业,我建议您学习更多关于指针、新/删除运算符、新[]/delete[]运算符(不要与新/删除运算符混淆)和对象创建/复制/构造函数/析构函数。它是基本C++特性,你的任务是关于这个的。
要指出一些方向:
1) 当您像这样动态地分配对象时
MyType* p = new MyType;
MyType* p = new MyType[n];
或
获取指向已创建对象的指针(new
为类型为MyType
的单个对象分配内存,并调用该对象的构造函数)
在完成对该对象的操作后,必须调用
delete p;
delete[] p; // not "delete p;"
delete
调用对象的析构函数,然后释放内存。如果不调用delete
,内存就会泄漏。如果您多次调用它,则行为是未定义的(可能是堆损坏,这可能导致程序崩溃—有时是在非常奇怪的时刻)
2) 当您像这样动态分配数组时
MyType* p = new MyType;
MyType* p = new MyType[n];
将指针p
指向按顺序位于内存中的n
创建对象的数组(new[]
为n
类型的MyType
对象分配单个内存块,并为每个对象调用默认构造函数)
无法更改此动态数组中的元素数。您只能删除它。
使用该数组的工作完成后,必须调用
delete p;
delete[] p; // not "delete p;"
delete[]
调用数组中每个对象的析构函数,然后释放m