I'm trying to understand the memory issues associated with dynamic struct arrays inside of dynamic struct arrays. I am dynamically creating an array of structs and attaching it to the variable 'persons' and then dynamically creating an array of structs and attaching it to the variable 'pets' inside of each 'persons' object. A simple example is this:
typedef struct {
int age;
} Pet;
typedef struct {
Pet *pets;
} Person
Create 2 Object Person array and attach it to variable 'persons'
persons = (Person*) ::operator new(sizeof(Person) * 2);
persons[0]
persons[1]
Create 3 Object Pet array and attach it to the variable 'pets' inside of object #1 of 'persons'
persons[0].pets = (Pet*) ::operator new(sizeof(Pet) * 3);
persons[0].pets[0].age
persons[0].pets[1].age
persons[0].pets[2].age
Create 2 Object Pet array and attach it to the variable 'pets' inside of object #2 of 'persons'
persons[1].pets = (Pet*) ::operator new(sizeof(Pet) * 2);
persons[1].pets[0].age
persons[1].pets[1].age
If I dynamically create another array of structs and attach it to the 'persons' array will the array previously attached to the variable 'persons' be free?
Create 4 Object Person array and attach it to variable 'persons' replacing the previous 2 Object array.
persons = (Person*) ::operator new(sizeof(Person) * 4);
persons[0]
persons[1]
persons[2]
persons[3]
If not, do I need to free each of the 'pets' arrays inside of each object of the 'persons' array?
Here it is in code running on an Arduino. The code works fine and seems to repeat indefinitely without any hiccups, but that doesn't mean it's legit.
// 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);
}