Several usages of returning local variables in C language -- (classic example)

        Generally speaking, functions can return local variables.   The scope of the local variable is only inside the function. After the function returns, the memory of the local variable has been released. Therefore, if the function returns the value of a local variable and does not involve an address, the program will not make an error. However, if the address (pointer) of the local variable is returned, an error will occur after the program runs.

        Because the function only returns after copying the pointer, but the content pointed to by the pointer has been released, so the content pointed to by the pointer is unpredictable, and the call will make an error. To be exact, a function cannot return a pointer to the stack memory (note that this refers to the stack, and it is possible to return a pointer to the heap memory).

Here are some typical examples of the pointer of a function returning a local variable:

1: Returns a pointer to a string constant

#include <stdio.h>
char *returnStr()
{
    char *p="hello world!";
    return p;
}
int main()
{
    char *str;
    str=returnStr();
    printf("%s\n", str);
    return 0;
}

      There is no problem with this because "hello world!" is a string constant stored in a read-only data segment, and the first address of the read-only data segment stored by the string constant is assigned to the pointer. Therefore, when the returnStr function exits, the memory of the string constant will not be recycled, so it can be accessed smoothly through the pointer.

2: Cannot return the first address of a string array created as a local variable

#include <stdio.h>
char *returnStr()
{
  char p[]="hello world!";
  return p;
}
int main()
{
  char *str;
  str=returnStr();
  printf("%s\n", str);
  return 0;
}

#include <stdio.h> char *returnStr() { char p[]="hello world!"; return p; } int main() { char *str; str=returnStr(); printf("%s\n", str); return 0; }   "Hello world!" is a local variable stored in the stack. When the returnStr function exits, the stack will be emptied and the memory of local variables will be emptied. Therefore, the function returns a memory address that has been released, so it may print out garbled code.

3: In a function, it is allowed to return the value of a local variable, but not the address of a local variable

int func()
{
  int a;
  ....
  return a; //allow
}
int * func()
{
  int a;
  ....
  return &a; //It's meaningless. It shouldn't be done
}
//allow
int func()
{ 
    int a; 
    .... 
    return a; 
} 
//It's meaningless. It shouldn't be done
int * func()
{ 
    int a; 
    .... 
    return &a; 
}

          Local variables also include local automatic variables and local static variables. Since a returns a value, it is possible to return a local variable, whether automatic or static, because it returns the value of the local variable, but it should not return a pointer to the local automatic variable, because the local automatic variable is discarded after the function call, This pointer to an object that no longer exists is meaningless. However, you can return a pointer to a local static variable because the lifetime of a static variable is from definition to the end of the program.

4: If the return value of a function is not the address of a local variable, the local variable must be declared as static. As follows:

#include <stdio.h>
char *returnStr()
{
  static char p[]="hello world!";
  return p;
}
int main()
{
  char *str;
  str=returnStr();
  printf("%s\n", str);
  return 0;
}

5:   Array cannot be used as the return value of a function because the compiler considers the array name to be the address of a local variable (array). Returning an array is generally replaced by returning a pointer to this array, and this pointer cannot point to an automatic array, because the automatic array is discarded after the end of the function, but a pointer to the static local array can be returned, because the static storage period is from the object definition to the end of the program. As follows:

int* func( void )
{
  static int a[10];
  ........
  return a;
}

6: It is possible to return a pointer to heap memory

char *GetMemory3(int num)
{
  char *p = (char *)malloc(sizeof(char) * num);
  return p;
}
void Test3(void)
{
  char *str = NULL;
  str = GetMemory3(100);
  strcpy(str, "hello");
  cout<<str<<endl;
  free(str);
}

         When the program is running, it uses malloc to apply for any amount of memory. The programmer is responsible for when to use free to release memory. The lifetime of dynamic memory is determined by the programmer, which is very flexible.

Tags: C

Posted on Mon, 22 Nov 2021 00:21:01 -0500 by Notre