In this forum question which I visited for a totally external problem to the aspect of this question, I saw an answer in which something quite interesting is mentioned (specifically the trauma response). In a part of the code of the user who asks the question (francesc), he returns the reference to a string in a function (or at least that was his intention) and the following is put in the answer...
Taking into account that rever is an automatic variable, whose lifetime is limited to the time it takes to execute your function, you will end up returning a pointer to a memory area that no longer contains what you expect.
This makes total sense, however, I started checking and something a bit unexpected happened...
code:
#include <stdio.h>
#include <stdlib.h>
char *cadena();
char *cadena(){
char *cadena = "Hola";
return cadena;
}
int main(){
int arreglo[20];
char *cadena2 = cadena();
printf("%s", cadena2);
return 0;
}
exit:
Hola
Basically even when the function returns the reference to an array that is supposed to no longer exist and also doesn't load into dynamic memory like it does in @trauma's answer, the string is returned normally... Bearing this in mind, The question would be: why is this happening? isn't the string return value supposed to die after the function has finished?
Regarding this, I have an assumption: when this type of allocation is actually made, the C compiler (in my case gcc 9.3.0, I'm on ubuntu at the moment) loads cadena
into dynamic memory and that is why there is still getting to the line 16.
Final edit: I've been doing a lot of testing and came to the following conclusion... Apparently, when arrays are created as 'raw' pointers, in functions, their value persists after function completion, otherwise it doesn't. .
Example 1:
code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *arreglo();
int *arreglo(){
int *array = (int *) calloc(sizeof(int), 2);
array[0] = 1;
array[1] = 2;
printf("referencia a array desde funcion <main> %i\n", array);
return array;
}
int main(){
printf("referencia a array desde funcion <main> %i\n", arreglo());
return 0;
}
exit:
referencia a array desde funcion <main> 642618016
referencia a array desde funcion <main> 642618016
example 2:
code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *arreglo();
int *arreglo(){
int array[2] ;
array[0] = 1;
array[1] = 2;
printf("referencia a array desde funcion <main> %i\n", array);
return array;
}
int main(){
printf("referencia a array desde funcion <main> %i\n", arreglo());
return 0;
}
exit:
referencia a array desde funcion <main> -258186320
referencia a array desde funcion <main> 0
Although I am checking this with examples, this may be working by many coincidences (unfortunately, this has already happened to me (^ _ ^) ), so it would be nice if someone who knew confirmed all this
Let's take your function:
And let's see the assembler that it generates:
If you notice, the string
"Hola"
is stored outside the function. It is as if it were a variable that you marked asstatic
, or a global variable . That's why you can access it outside of the function, it doesn't get destroyed. This is what is usually done with literal strings.It is equivalent to this:
Rather save the string in the section
text
of your executable (I may be misremembering the name).With this:
I assume you mean this example:
That they are cleaned after the function is finished only applies to variables that are on the stack. If you use
calloc
, you are allocating memory on the heap, and it will be there until you free it usingfree
.Stack variables die when they go out of scope (the
{}
). These are the ones you normally declare:Then there are the static variables inside the functions, which will last from when they are initialized, until the program ends.
There are the global variables that will last the entire program, and finally there is the memory that you allocate using
malloc
andcalloc
, which will be available until you free it usingfree
.What happens is that the literal
"Hola"
is stored in read-only memory while the variablecadena
is stored on the stack . What is stored in this variable is the memory address of the string.In general, if the string is in an array definition, it will be placed on the stack as well:
And if they are stored in a pointer it will go to read-only memory.
It's not a sure thing as it varies by compiler.
Sources: https://stackoverflow.com/a/349030 https://stackoverflow.com/a/2589963 https://stackoverflow.com/a/14468729/13419694
Perhaps you have the doubt because the strings you declare are static, imagine that when you compile your program all the strings you declare
"de esta forma"
have to go inside your binary, if not, where are you going to get them from?so when you do the assignment
char *cadena_estatica = "Cadena Interna"
you're setting the pointer to a static string which lives in your binary and lives for the entire execution of the program; when you finally return it you're just passing the memory address of the static string, so we know for a fact that it's a valid memory space.
Now let's create the string ourselves inside the function and programmatically:
and the program fails as you are now pointing to a page that has already been discarded.