Is it safe to return?

7

Why is it safe to return string2? at the end of the function the stack frame would not be overwritten? I have seen that many compilers save the literal "hello" in a memory-only zone, which is why it is safe to return string2 without the stack frame being overwritten?
Greetings and thanks in advance

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *imprimir_cadena( char *cadena2 ) {
  return cadena2;
}


int main( ){
  char *ptr = "hola";
  char *p = imprimir_cadena( ptr );

  printf( "%s", p );

  return 0;
}
    
asked by Maur 08.05.2018 в 21:56
source

3 answers

7

The return you make is safe, regardless of whether the literal is stored in a read-only zone or not.

To understand why it's safe, look at this other case:

int ejemplo(int valor)
{
   return valor;
}

Do you find this code dangerous? Obviously not, because you are returning a copy of the valor that you have received as a parameter. Although the variable valor exists in the stack and only while the function is executed, the return evaluates the expression valor , and returns the result of that expression.

The same is true when the expression is a pointer. What returns is the value of the pointer, that is, the direction it points to (which is the same address pointed to by ptr in your example, which is outside the stack of that function).

    
answered by 08.05.2018 / 22:05
source
4

In your code, both p and ptr point towards the same memory address, that is, towards the constant address "hola" , that it is safe, it is safe, since you only pass it as an argument to the function, which does not prevent your address from changing, now, if you do:

#include <string.h>

char *imprimir_cadena(char *cadena2) {
  char cad[50];
  if (cadena2)
    memcpy(cad, cadena2, strlen(cadena2));
  return cad;
}

Some compilers will complain that you are returning a local variable, others do not (And those that allow you to return, optimize the memory address of cad ) , the important thing here is that with the method that I put above you invoke indefinite behavior, but the way you propose it, it is totally safe to return the same pointer that was received as an argument.

    
answered by 08.05.2018 в 22:05
4
  

Why is it safe to return string2? at the end of the function the stack frame would not be overwritten?

cadena2 is a pointer yes, and it is also local ... but the memory pointed to by no is local, then the memory pointed to by cadena2 is not going to happen nothing once the program leaves the function. Something else would happen if we use memory belonging to the function itself:

char* func2()
{
  char cadena2[] = "hola";
  return cadena2; // <<--- cuidado!!!
}

int main()
{
  char* ptr = func2();
  puts(ptr);
  return 0;
}

The program will also compile but we do not get the expected result ...

  

I've seen many compilers save the literal "hello" in a memory-only zone, which is why it's safe to return string2 without the stack frame being overwritten?

It's safe because the region of memory it points to remains valid after the program leaves the function.

For the code that I have put you before to work properly, it would be enough, for example, to declare the variable cadena2 as static:

char* func2()
{
  static char cadena2[] = "hola";
  return cadena2;
}

In this way the variable cadena2 does not die with the function. Another possibility would be to use dynamic memory:

char* func2()
{
  char* cadena2 = (char*)malloc(5*sizeof(char));
  strcpy(cadena2,"hola");
  return cadena2;
}

int main()
{
  char* ptr = func2();
  puts(ptr);
  free(ptr); // No olvidemos liberar la memoria
  return 0;
}

The only requirement that we have to fulfill, therefore, is that the region of memory returned by the pointer is valid outside the function.

    
answered by 09.05.2018 в 08:37