Function returns pointer to data that is located on the stack.

Hi,

Sometimes I see code that returns a pointer to data, and that data is declared inside the function.
When that data is static, I'm willing to look the other way. However, outside the function the variable is out of scope. Sometimes I see it without the word 'static'.

Do you consider this as normal 'c' code ?

char * test()
{
  static char data[16];
  strcpy( data, "Hello World");
  return( data);
}

I think this is terribly wrong. I hope you agree.

char * test()
{
  char data[16];
  strcpy( data, "Hello World");
  return( data);
}

After doing some tests, it seems that it sometimes works.
It depends on the compiler version, the compiler optimization options, the code, and so on.

Here is a test sketch for Arduino 1.6.1 and Arduino Uno board.
Set the size to 16 and it goes terribly wrong. Set the size to 128, and it works :astonished:

// #define SIZE 16
#define SIZE 128

void setup() 
{
  Serial.begin( 9600);
  Serial.println("\nStarted");
}

void loop() {
  char *p;
  
  p = test();
  Serial.print( p);
  Serial.print( ", ");
  p = overwrite();
  Serial.print( p);
  Serial.println();
  
  delay(1000);
}

char *test()
{
  char data[SIZE];
  strcpy( data, "Hello World");
  return( data);
}

char *overwrite()
{
  char overdata[SIZE];
  strcpy( overdata, "XXXXXXXXXXXXXX");
  return( overdata);
}

It is not at all dependant on compiler version, it is entirely a function of exactly how the code is written, and follows the rules of the C language. In your first example, data is declared as static, which means it exists on the heap, not the stack, so persists whether the function is being executed or not. In your second example, data is NOT declared as static, so it exists on the stack, and may, or may not, remain intact after the function returns, depending on other stack activity. The first example is perfectly valid, and safe, C code. The second is very bad, and dangerous, C code. Your third example works if the array size is large because the "Hello world" string ends up lower down in memory, due to the array length, so you are accessing it before it has been over-written by other stack activity. It is still very poor code that WILL fail at some point.

Regards,
Ray L.

Thanks.
Okay, I accept that using 'static' is perfectly valid. Even if the variable itself is out of scope, the actual data is safe and sound in a fixed ram location.

I really did see the very bad example a couple of times.