Expert C Programming

(Jeff_L) #1

/ convert the tm struct into a string in local format /


strftime(buffer, sizeof(buffer), "%a %b %e %T %Y", tm_ptr);


return buffer;


}


See it? Time's up! The problem is in the final line of the function, where the buffer is returned. The
buffer is an automatic array, local to this function. Automatic variables go away once the flow of
control leaves the scope in which they are declared. That means that even if you return a pointer to
such a variable, as here, there's no telling what it points to once the function is exited.


In C, automatic variables are allocated on the stack. This is explained at greater length in Chapter 6.
When their containing function or block is exited, that portion of the stack is available for reuse, and
will certainly be overwritten by the next function to be called. Depending on where in the stack the
previous auto variable was and what variables the active function declares and writes, it might be
overwritten immediately, or later, leading to a hard-to-find corruption problem.


There are several possible solutions to this problem.



  1. Return a pointer to a string literal. Example:


2.


char *func() { return "Only works for simple strings"; }


This is the simplest solution, but it can't be used if you need to calculate the string contents, as
in this case. You can also get into trouble if string literals are stored in read-only memory, and
the caller later tries to overwrite it.


  1. Use a globally declared array. Example:


4.


5. char *func() {


6. ...


7. my_global_array[i] =


8. ...


9. return my_global_array;


}


This works for strings that you need to build up, and is still simple and easy to use. The
disadvantages are that anyone can modify the global array at any time, and the next call to the
function will overwrite it.


  1. Use a static array. Example:


11.


12. char *func() {


13. static char buffer[20] ;


14. ...


15. return buffer;


}

Free download pdf