Returning Pointer to Char Array; I Get Junk?

Peoples,

I’m making a call to a function that creates an array of char and populates it. The function returns a pointer to the newly created array. When the pointer is received by the calling function, the data has been junked and no longer contains the expected characters. Here’s my code:

void setup()
{
  Serial.begin(115200);
  Serial.println("setup()");

  char* back = stuff();
  Serial.print("Returned at address: ");
  Serial.println((unsigned int) back);
  Serial.print("Returned Array:    >>");
  Serial.print(back);
  Serial.println("<<");
}

void loop()
{
}

char* stuff()
{
  char helloWorld[] = "Hello World";
  Serial.print("Created at address:  ");
  Serial.println((unsigned int) helloWorld);
  Serial.print("Created Array:     >>");
  Serial.print(helloWorld);
  return helloWorld;
  Serial.println("<<");
}

And the output:

setup()
Created at address:  2278
Created Array:     >>Hello World<<
Returned at address: 2278
Returned Array:    >>B<<

I can guess as far as this: the array must go out of scope at the end of the stuff() function. So its memory is available to be overwritten. But what is there to write over it? Nothing else is going on. Shouldn’t the data still be there - even if the helloWorld variable’s out of scope. I know it’s a “dangerous read” at that point, but what’s junking the data?

I’ve tried a similar thing with String. When stuff() creates a String object and returns a reference everything works fine. Please set me straight. I’m not getting this. Thanks!

helloWorld is created on the stack. When stuff() returns helloWorld will most likely still be in memory. Then you continue to call other functions (Serial.* in your case). These use the stack and overwrite the out-of-scope helloWorld.

Memory used by the String class is taken from the heap. When this is free'd it will still be visible until that part of the heap is used again. This is not behaviour to rely on. Without checking the code I think that String implements the required constructors and operators for you to be able to safely return it from a function without using pointers or references.

char* stuff()
{
static char helloWorld = “Hello World”; // keeps the char array alive outside the function
Serial.print("Created at address: ");
Serial.println((unsigned int) helloWorld);
Serial.print(“Created Array: >>”);
Serial.print(helloWorld);
return helloWorld;

Serial.println("<<"); // CODE NEVER REACHED
}

[quote author=Andy Brown link=topic=52134.msg371824#msg371824 date=1297627679]
…String implements [/quote]The various string functions return a copy of the string object so that the calling function can do whatever the heck it wants to do with it. (All of the local variables inside the function are out of scope when the function returns, and it is never OK to access them.)

A function like the Original Poster’s “stuff()” returns a copy of a pointer to some memory that is out of scope when the function returns.

C and C++ programs can not (that’s not) return arrays just by returning a variable that is the name of the array. The name of an array is a pointer whose value is the address of the first element of the array. That’s what the calling program gets to work with. A pointer.

When the array goes out of scope, trying to access its memory with the pointer value that was returned results in “undefined behavior.”

Sometimes (depending on the compiler and on various details of what is being done) it might even seem to “work.” But, if you are lucky, it will show you some garbage when you try to do such things, so that you will know that there is a bug to be fixed. It’s not only “dangerous,” it’s positively, absolutely, unequivocally wrong to indulge in such nonsense. I mean, if you accidentally write a code with undefined behavior, it might be difficult to debug, but if you do it on purpose because you tried it and it “worked,” well, that’s just too awful for words.

The ever-present possibility of undefined behavior is one reason that C programs, in general, can not be proved to be correct by testing alone. Even if it seems to be acting the way that you expect, undefined behavior is that snake in the grass waiting for you to walk by so that it can reach out and bite you on the ankle. (Or, maybe stretch out and bite you a little higher up.)

Regards,

Dave