A problem I am having with returning an array of objects

Hi All,

I would like a function to return an array of objects. Having tried a number of approaches I have not yet managed to come to a solution that works yet.

By way of example I have written a class called person which has a static function called getTwoRandomPeople. Its purpose is to create two people and return a Person array of size 2. Please see the Person class below:

#include "Person.h"

Person::Person(String iName) {
	name = iName;
}

Person::~Person() {
}

String Person::getName(){
	return name;
}

Person* Person::getTwoRandomPeople(){
	Person *people[2];
	Person *p1 = new Person("Brian");
	Person *p2 = new Person("Liam");

	people[0] = p1;
	people[1] = p2;
	return people[0];
}

In my sketch I am attempting to access each Person and output the name. See below:

#include "Person.h"

void setup()
{
	Serial.begin(9600);
	Serial.println("starting");
	Person *people = Person::getTwoRandomPeople();
	for (int i=0;i<2;i++){
		Serial.println(people[i].getName());
	}
}

void loop()
{
}

The output to the Serial monitor is the following

starting
Brian
e%L%,%u%

As you can see the second person is not correctly outputting the name.

If someone can tell me how I should approach this problem, it would be greatly appreciated.

Thanks again,

Brian

p.s. A few words on the development environment:
I am using eclipse with the plugin from here: Arduino Eclipse IDE named Sloeber - Welcome!

Your array "people" is a dynamic variable that gets thrown away when you exit the function.

You could use the 'static' keyword to make it persist and it will get overwritten when you call the function again.

The safest way is to pass the empty array as a function argument and fill it up. I think something like this would work:

void Person::getTwoRandomPeople(Person people[2]){
	people[0] = new Person("Brian");
	person[1] = new Person("Liam");
}

.
.
.
     Person people[2];
     Person::getTwoRandomPeople(people);
	for (int i=0;i<2;i++){
		Serial.println(people[i].getName());
	}

You should be aware that using dynamic object allocation like this can be problematic on Arduino since you have very little memory and very little scope for compacting the heap when it becomes fragmented. But this isn't the cause of your problem.

You could solve it by dynamically allocating the array and returning the array and its contents, and making the caller responsible for freeing them all. It's taking you further down the dangerous path of using dynamic memory allocation, and I'd advise against it, but that's the simplest approach to return an array of unknown size. If the return array is a predictable size, simply have the caller provide it as an argument passed in to the method.

Thanks Peter,

It looks like a great solution. I will try that at the weekend.

John,

I had not mentioned in my original post that I had previously come to the conclusion that my library must dynamically allocate objects(I may be wrong).

The program will only know at run time what number of objects will be created. Preferably I would like this number to be boundless but I know that will certainly cause me a problem with memory. Having said that the (dynamically allocated) objects will only be created at startup so a failure to allocate the memory will bring down the startup of the sketch.

I decided that to get around this I would limit the number of objects by allocating an array (e.g with size 10) and fill it up as the program determines the number of objects. Then I can stop filling up the array when I get to the last element. I could then experiment with the size of the array to see how many objects I can fit in at startup.

I am (relatively) new to c++ so I am still learning syntax and the way things are done. Of course improvement suggestions to my approach or otherwise are very welcome.