当动态创建一个包含另一个动态创建的结构数组的结构数组时,内存管理
Memory management when dynamically creating an array of structs that contain another dynamically created array of structs
我正在尝试了解与动态结构数组内部的动态结构数组相关的内存问题。我正在动态创建一系列结构,并将其附加到变量"人"上,然后动态创建结构数组,并将其连接到每个"人"对象的内部变量"宠物"。一个简单的例子是:
typedef struct {
int age;
} Pet;
typedef struct {
Pet *pets;
} Person
创建2个对象人员阵列并将其连接到可变的"人"
persons = (Person*) ::operator new(sizeof(Person) * 2);
persons[0]
persons[1]
创建3个对象宠物数组,然后将其连接到"人"
的对象#1的变量"宠物"persons[0].pets = (Pet*) ::operator new(sizeof(Pet) * 3);
persons[0].pets[0].age
persons[0].pets[1].age
persons[0].pets[2].age
创建2个对象pet数组,然后将其连接到"人"
的对象2的变量"宠物"persons[1].pets = (Pet*) ::operator new(sizeof(Pet) * 2);
persons[1].pets[0].age
persons[1].pets[1].age
如果我动态创建另一个结构数组并将其连接到"人"数组,以前将数组附加到变量"人"中?
创建4个对象人员阵列,并将其连接到变量的" persons",以替换前两个对象数组。
persons = (Person*) ::operator new(sizeof(Person) * 4);
persons[0]
persons[1]
persons[2]
persons[3]
如果没有,我需要释放"人"数组每个对象的每个"宠物"阵列?
这里是在Arduino上运行的代码中。该代码工作正常,似乎无限地重复没有任何打ic,但这并不意味着它是合法的。
// DYNAMIC MEMORY
// OBJECTS
// Pet object
typedef struct {
char *name;
int age;
} Pet;
// Person object
typedef struct {
char *name;
int age;
int numberOfPets;
Pet *pets; // OBJECT 'Pet' is part of OBJECT 'Person'
} Person;
#define OBJECT_PET 0
#define OBJECT_PERSON 1
// DYNAMIC MEMORY HANDLING
// ARRAY Creation
void* createArray(int numberOfObjects, int typeOfObject) {
numberOfObjects;
int memorySize;
switch (typeOfObject) {
case OBJECT_PET:
Serial.print("Creating Pet array of ");
memorySize = sizeof(Pet) * numberOfObjects;
break;
case OBJECT_PERSON:
Serial.print("Creating Person array of ");
memorySize = sizeof(Person) * numberOfObjects;
break;
}
Serial.print(numberOfObjects);
Serial.println(" objects");
return ::operator new(memorySize);
}
// GLOBAL VARIABLES
Person *persons;
int numberOfPersons;
void createPersonsAndPetsFirst() {
numberOfPersons = 3;
// CREATE 3 empty Person objects [0, 1, 2]
persons = (Person*) createArray(numberOfPersons, OBJECT_PERSON);
// ENTER Specific Person information for Person #1
// Person #1 [0]
persons[0].name = "Larry";
persons[0].age = 19;
persons[0].numberOfPets = 2;
// CREATE 2 empty Pet objects for Person #1
persons[0].pets = (Pet*) createArray(persons[0].numberOfPets, OBJECT_PET);
// ENTER Specific Pet information for Pet #1
// Pet #1
persons[0].pets[0].name = "Xander";
persons[0].pets[0].age = 3;
// ENTER Specific Pet information for Pet #2
// Pet #2
persons[0].pets[1].name = "Shorty";
persons[0].pets[1].age = 6;
// ENTER Specific Person information for Person #2
// Persons #2 [1]
persons[1].name = "Mark";
persons[1].age = 29;
persons[1].numberOfPets = 1;
// CREATE 1 empty Pet object for Person #2
persons[1].pets = (Pet*) createArray(persons[1].numberOfPets, OBJECT_PET);
// ENTER Specific Pet information for Pet #1
// Pet #1 [0]
persons[1].pets[0].name = "Fido";
persons[1].pets[0].age = 5;
// ENTER Specific Person information for Person #3
// Person #3 [2]
persons[2].name = "Larry";
persons[2].age = 19;
persons[2].numberOfPets = 2;
// CREATE 2 empty Pet objects for Person #1
persons[2].pets = (Pet*) createArray(persons[0].numberOfPets, OBJECT_PET);
// ENTER Specific Pet information for Pet #1
// Pet #1
persons[2].pets[0].name = "Nado";
persons[2].pets[0].age = 12;
// ENTER Specific Pet information for Pet #2
// Pet #2
persons[2].pets[1].name = "Buster";
persons[2].pets[1].age = 4;
Serial.println();
}
void createPersonsAndPetsSecond() {
numberOfPersons = 2;
// CREATE 2 empty Person objects [0, 1]
persons = (Person*) createArray(numberOfPersons, OBJECT_PERSON);
// ENTER Specific Person information for Person #1
// Person #1 [0]
persons[0].name = "Chad";
persons[0].age = 22;
persons[0].numberOfPets = 1;
// CREATE 1 empty Pet object for Person #1
persons[0].pets = (Pet*) createArray(persons[0].numberOfPets, OBJECT_PET);
// ENTER Specific Pet information for Pet #1
// Pet #1
persons[0].pets[0].name = "Lucky";
persons[0].pets[0].age = 5;
// ENTER Specific Person information for Person #2
// Persons #2 [1]
persons[1].name = "Lisa";
persons[1].age = 36;
persons[1].numberOfPets = 2;
// CREATE 2 empty Pet objects for Person #2
persons[1].pets = (Pet*) createArray(persons[1].numberOfPets, OBJECT_PET);
// ENTER Specific Pet information for Pet #1
// Pet #1 [0]
persons[1].pets[0].name = "Chester";
persons[1].pets[0].age = 7;
// ENTER Specific Pet information for Pet #2
// Pet #2 [1]
persons[1].pets[1].name = "Marlo";
persons[1].pets[1].age = 12;
Serial.println();
}
void sendPersonsAndPetsInformationToHost() {
Serial.print("Number of Persons = ");
Serial.println(numberOfPersons);
for (int personsIndex = 0; personsIndex < numberOfPersons; personsIndex++) {
// SHOW Person
Serial.print("Person #");
Serial.print(personsIndex + 1);
Serial.println(" Information");
// SHOW Person Information
Serial.print("Name = ");
Serial.println(persons[personsIndex].name);
Serial.print("Age = ");
Serial.println(persons[personsIndex].age);
// SHOW Person number of Pets Information
Serial.print("Number of Pets = ");
Serial.println(persons[personsIndex].numberOfPets);
for (int petsIndex = 0; petsIndex < persons[personsIndex].numberOfPets; petsIndex++) {
// SHOW Pet
Serial.print("Pet #");
Serial.print(petsIndex + 1);
Serial.println(" Information");
Serial.print("Name = ");
Serial.println(persons[personsIndex].pets[petsIndex].name);
Serial.print("Age = ");
Serial.println(persons[personsIndex].pets[petsIndex].age);
}
Serial.println();
}
}
void setup() {
// OPEN Serial communication
Serial.begin(115200);
}
void loop() {
// CREATE First Persons and Pets Arrays
createPersonsAndPetsFirst();
// SEND Persons and Pets array information to Host
sendPersonsAndPetsInformationToHost();
delay(2000);
// CREATE Second Persons and Pets Arrays
createPersonsAndPetsSecond();
// SEND Persons and Pets array information to Host
sendPersonsAndPetsInformationToHost();
delay(2000);
}
no 先前分配的内存将不会被释放。您将失去所有分配的内存。
通过覆盖您的persons
指针,您会在分配的存储中丢失手柄。因此,在您这样做之前,您必须致电
::operator delete(persons[0].pets);
::operator delete(persons[1].pets);
::operator delete(persons);
这很丑陋,不是吗?因此,存在std::vector
容器。
#include <vector>
struct Person {
std::vector< Pet > pets;
};
std::vector< Person > persons(2);
persons[0].pets = std::vector< Pet >(2);
persons[1].pets = std::vector< Pet >(3);
persons = std::vector< Person >(3); // won't lose memory
由于您可能没有听说过,我建议您在RAII或这里阅读。
简而言之,不,您需要删除它们。
您创建的第一人称阵列将成为垃圾,因此在将另一个数组分配给指针之前,您应该将其删除(免费)。(将"新"操作员视为访问内存位置的请求权限(键),因此,如果您丢失了该位置的地址,您将无法再使用它,也不会再使用它(因为您有钥匙!),因此变成垃圾。)
现在,如果您删除了该阵列,您仍然将宠物阵列作为垃圾,因此您应该先删除它们(否则您没有其地址,再一次,又是垃圾!),然后删除人阵列。
更好的(和标准)方法是为人编写攻击方法,并删除其中的宠物阵列。当一个人对象被删除时,将自动调用破坏者。
- 从函数中全局删除并重新实例化数组结构,而无需在编译时知道数组的大小
- 如何使用函数的输出初始化 const 数组结构字段?
- 传递数组结构、ofstream 和 interger 以运行
- 从文本文件中读取并输入到数组结构中,然后显示读取的数据C++
- 将文本文件读取到数组结构中
- C/C++中数组结构和数组结构的通用接口
- C++ MDC final-在字符类型的数组结构中按字母顺序对记录中的名称进行排序
- C++ 使用数组结构创建平衡的二叉搜索树
- C++:释放动态数组(结构成员)和指向此结构的指针的方法
- 使用 vector 在 c++ 中声明 3D 数组结构
- 数组结构无法正确打印
- 如何在C++中访问数组结构内部的数组结构
- CIN进入数组结构似乎什么也没输入
- ifstream将数组结构到txt文件中,然后尽可能将其提取为数组
- wlanapi-将WlanFreeMemory释放其WLAN_INTERFACE_INFO数组结构
- 显示数组结构 c++
- C++ 使用函数访问数组结构的方法是什么?
- 将庞大的数组结构复制到 GPU
- 如何封送包含字符矩阵的数组结构
- C++多维数组结构的对齐