Can a function return a char array?

I would like to write a function returning a char array.Is this possible or do I have to declare a public variable?

You can return a pointer to a char array. This could be because the function chooses among pre-allocated arrays, or it could dynamically allocate one, though you must be very careful with dynamic allocation in the very limited RAM environment of the arduino.

As the array has a maximum length of the char array is set to 255 a public variable need not to be dynamic, but as my code gets bigger I try to avoid public variables because otherwise the code gets too confusing.
An other way would be to return a string and re-convert it into a char array, but this isnt nice either...

You could return a struct, containing a char array.
Probably not recommended.

You can return a char array, but you need to be cautious about how that array comes into existence. Here is an example:

char * foo ()
{
 char buf [666] = "But does it get goat's blood out?";
 return buf;
}  // end of foo

void setup ()
{
  Serial.begin (115200);
  Serial.println (foo ());
}  // end of setup

void loop () {}

This code however has a fundamental flaw, which I will point out before my colleagues do. :wink:

The character array buf has a scope and lifetime only inside foo, and thus although I returned a pointer to it, the pointer becomes invalid outside foo. Thus it prints garbage (as expected).

This "fixes" it:

char * foo ()
{
 static char buf [666] = "But does it get goat's blood out?";
 return buf;
}  // end of foo

void setup ()
{
  Serial.begin (115200);
  Serial.println (foo ());
}  // end of setup

void loop () {}

Now the scope of buf is inside foo, but the lifetime is the whole sketch. This prints correctly, but by making it static I may as well have made it a global variable. The memory (666 bytes) is going to be used, whether or not I am inside foo.

In other words, like this:

char buf [666] = "But does it get goat's blood out?";

char * foo ()
{
 return buf;
}  // end of foo

void setup ()
{
  Serial.begin (115200);
  Serial.println (foo ());
}  // end of setup

void loop () {}

Now of course, foo is pretty useless.

You can dynamically allocate memory:

char * foo ()
{
 char * buf = (char *) malloc (666);
 strcpy (buf, "But does it get goat's blood out?");
 return buf;
}  // end of foo

void setup ()
{
  Serial.begin (115200);
  Serial.println (foo ());
}  // end of setup

void loop () {}

That works, but the memory is never reclaimed. So you could do this:

char * foo ()
{
 char * buf = (char *) malloc (666);
 strcpy (buf, "But does it get goat's blood out?");
 return buf;
}  // end of foo

void setup ()
{
  Serial.begin (115200);
  char * p = foo ();
  Serial.println (p);
  free (p);
}  // end of setup

void loop () {}

That is closer, foo allocates as much memory as it wants to (within reason) and setup does something with the char array, and then frees it.

I would like to write a function returning a char array.Is this possible or do ...

As I hope I have demonstrated, the answer is "yes". But bear in mind you don't have a lot of memory to play with.

9 Likes

It uses the same amount of memory whether it's on the stack or the heap, though...

If you clean up the buffer right after the function call (or maybe you use the result in another function, then you clean it), there's nothing to worry about.

1 Like

I'm not sure I understand that. My first example (which uses the stack) actually prints garbage, because the buffer on the stack has become invalid by the time you return from the function.

I am Brazilian and I thank you for sharing the experience, Nick. I tested the example, but the string that appears in the Serial Monitor is not the same . It appears several strange characters .
When I set a global variable and I exhibit in VOID SETUP with the CHAR function , it's all right, but when I display the local variable with the return value of the function, do not understand anything written .
My IDE is the latest 1.6.4 .

The results display in the Serial Monitor is this : èÈ

It's OK! I got!