It is not safe. The reason is simple:
Any variable on a function will be allocated on the stack whose memory is freed after the function returns. The fact that the memory is freed does not mean that its content is changed.
This means that the memory content you did put in the variable char buff[20]
is still at the buff
or ptr
(since ptr=buff
) memory position. Whenever you call another function (or execute another block), its function/block variables will go to the stack too, creating the possibility of changing the memory content for whose the position ptr
points to.
In the strcpy
example you wrote, you were lucky enough that the strcpy function variables did not get on the stack at a position that were inside the old buff
array. This is the reason you got the impression that it was safe.
The conclusion is that there is no way you can really guarantee that a freed memory content of the stack will not change between two function calls.
The solution is to use malloc
because malloc
does not allocate memory on the stack but on the heap. Heap memory is not deallocated unless you chose to do so (by a free call).
This approach would guarantee that the memory pointed by ptr
is safe to be used by any other function.
The drawback of this solution is intrinsic: once the memory is not deallocated unless you programatically do that, if you forget to free this memory and lose the content of ptr
, this memory will be there, allocated for your program but never achievable, lost for as long as your program runs. This memory will become a memory leak :-)
This is one reason why some languages have garbage collectors... but this is another story :-)
PS.: I think that it is safe (if your program is single threaded), although I do not recommend, to do something like that:
{
char safe_buffer[20];
char *unsafe_ptr;
int i;
unsafe_ptr = f1();
/*Copy the buffer without calling any function
not to change the stack content
*/
for(i=0;i<20 && *(unsafe_ptr + i) != 0;i++)
{
*(safe_buffer + i) = *(unsafe_ptr + i);
}
*(safe_buffer + i) = 0;
f2(safe_buffer);
}