The first is returning a pointer to a static area of code that is always available. The text already exists inside the executable.
The second is returning a pointer to an area of the stack, which may or may not be available when the function terminates. At the end of it there is an unstack, so all the content that was in the stack when this function was running can no longer be accessed, so an attempt to access that area is an error (although by coincidence it might be possible if the data has not yet been deleted, but you should not trust it ever.)
Note that even in the second example there is text in the static area to play in the p
variable. When you run the line there the static area content is copied to the stack and p
has the address of that area, not static.
Arrays are types by value and therefore their value is in the storage area where it was declared. The local variable is its storage location.
You can only access an object outside a function where it was created if it is in the static area already present in the code or in heap , where you are responsible for #
Understand What are and where are the stack and heap? .
When you have to receive text that comes from a function, the correct one is to allocate the memory in the function that is going to use and pass the address of this allocated place to the function that will generate the text, so this function has all the responsibility of allocating and free up memory. You should always do so. All philosophy of C is on top of this.
There are those who think that a lot of code and the allocation should go in the function that generates the text, but this is not suitable. It works on simple systems, but getting to do bigger things is too risky to have to manage allocation and release in different places.
If you use the text only there and it is guaranteed that it is not absurdly large you can allocate it in stack . So just declare the array and you do not need to release it because what is in the stack is automatically managed.
But there is a problem, this requires you to make a copy of the text. If it's small okay, if it's large it's not efficient. The solution given in the other answer does not work in all situations and has compiler that does not even compile.
So almost always the solution is to allocate in heap .
I made an example of the wrong way to allocate memory in the heap within the function that generates the text and let anyone calling this function worry about the release. But that leaves room for the person to forget to do or do at the wrong time, creating serious problems. You are responsible for managing the lifetime of the heap object. So it's best to always pair with malloc()
and free()
.
As the dynamic allocation in heap can fail you have to check if it worked before doing anything in this memory location.
I also copied because to work in any situation. So in this case it is not efficient either.
So what's the solution? The first example of the question is the best way in most cases because it only takes text that is already in static area efficiently. It will only be a problem if you need to change this value. You can not move the static area, just copying. Most of the time you do not have to move.
I would only change the type of return to char *
.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void teste(char texto[10]) {
strcpy(texto, "Ponteiro"); //isto não é seguro, mas sabemos que funciona neste caso
}
char *teste2() {
char *texto = malloc(10);
if (texto != NULL) strcpy(texto, "Ponteiro"); //neste caso dá para eliminar isto, deixei porque o normal é fazer assim
return texto;
}
int main () {
char texto[10];
teste(texto);
printf("\nRESULTADO: %s\n", texto);
//segunda forma não recomendada
char *texto2 = teste2();
if (texto2 != NULL) {
printf("\nRESULTADO: %s\n", texto2);
free(texto2); //tem que librar a memória que foi alocada por outra função
}
}
See running on ideone . And no Coding Ground . Also put it in GitHub for future reference .
See more at: