Pointers as Function Returns

In this tutorial, we will learn about pointers as return types for functions or pointers as function returns. A pointer is just another data type. It stores the address of another data type. It is possible for a function to return pointer. However, we must understand the use cases in which we may want to return a pointer from a function.

For example, you want to return a value which you have computed inside a function but local variables life time is the life time of a function stack frame only. In other words, the value of a local variable will also be destroyed as soon as the function returns.

There are two ways to return a value from a function either through a value or through a reference or a pointer. In this tutorial, we will discuss how to return value as a pointer.

You can learn about pointers by reading these topics:

Let’s first revise our concept of calling a function by value.

Call by Value

To understand this concept better let us first look at a sample C program where we are using the concept of ‘call by value.’

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

int Subtract(int x, int y){
    int z = x-y;
    return z;
}
int main() {
    int num1 =10;
    int num2=2;
    int output= Subtract(num1,num2);
    printf("Subtract: %d\n",output);
}

How the Code Works?

We have a function Subtract() that takes in two integers as arguments. Subtract these two numbers and return the answer in a variable ‘z’.

In the main() method we will initialize two integer variables ‘num1’ and ‘num2’ and store some values in them. Another variable ‘output’ will be the return of the function Subtract(). We will pass ‘num1’ and ‘num2’ as arguments to this function. Then we will print the output.

Now let’s see the code output. After the compilation of the above code, you will get the following output.

Pointers as Function returns pic1

As you may notice we had passed the arguments 10 and 2 inside the Subtract() function hence we received an output of (10-2)=8.

‘num1’, ‘num2’ and ‘output’ are local variables to main() function and ‘x’, ‘y’ and ‘z’ are local variables to Subtract() function. When we call the Subtract() function, the value in the variable ‘num1’ of main is copied to the variable ‘x’ of Subtract(). Likewise, the value in ‘num2’ is copied to the variable ‘y’ of Subtract().

Modifying the Code

  • If we name variables in main() as ‘x’, ‘y’ and ‘z’ instead, still we will get the same output printed as before.
#include <stdio.h>
#include<stdlib.h>

int Subtract(int x, int y){
    int z = x-y;
    return z;
    printf("Address of 'x' in Subtract: %d\n",&x);
}
int main() {
    int x =10;
    int y=2;
    printf("Address of 'x' in main: %d\n",&x);
    int z= Subtract(x,y);
    printf("Subtract: %d\n",z);
}

Now what happened was that the value of ‘x’ in main is copied to the variable ‘x’ in Subtract and the value of ‘y’ in main is copied to the variable ‘y’ in Subtract. The ‘x’ in main and the ‘x’ in Subtract are not the same. The same is true for the ‘y’ in both the functions. We can verify that by printing the addresses of the variable ‘x’ in both functions.

After the compilation of the above code, you will get the following output.

Pointers as Function returns pic2

As you see, the address of ‘x’ in main is different from the address of ‘x’ in Subtract. This suggests that both are the variables are not the same and at different memory addresses.

The names of variables are local or specific to a particular function. In our example, the main() function can be called ‘calling function’. The Subtract() function can be called ‘called function.’ The call in which ‘x’ and ‘y’ in main are getting copied to ‘x’ and ‘y’ of Subtract is called a ‘call by value.’

Let’s first revise the concept of call by value.

Call by Reference

We have modified the previous example code so that now we will use the concept of call by reference instead of call by value.

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

int Subtract(int* x, int* y){
    printf("Address of 'x' in Subtract = %d\n",&x);
    printf("Value in 'x' of Subtract (address of 'x' in main) = %d\n",x);
    printf("Value at address stored in 'x' of Subtract = %d\n",*x);
    int z = (*x)-(*y);
    return z;
}
int main() {
    int x =10;
    int y=2;
    printf("Address of 'x' in main: %d\n",&x);
    int z= Subtract(&x,&y);
    printf("Output: %d\n",z);
}

How the Code Works?

Instead of passing by value, we want to pass the addresses of these two variables ‘x’ and ‘y’ to the Subtract() function instead. The signature of Subtract() function should be such that it should receive the addresses. It will take two pointers to integers ‘x’ and ‘y.’

int Subtract(int* x, int* y)

We can access the values at these addresses by using the * operator that is used to dereference an address. This call will now be ‘call by reference.’

‘x’ and ‘y’ are integers local to the main() function whereas in the Subtract() function ‘x’ and ‘y’ are pointer variables. They are pointers to integers. These ‘x’ and ‘y’ pointer variables are local to the function Subtract(). Using these two pointer to integers variables we will access the ‘x’ and ‘y’ variables in the main() function. This will be done by using the * operator.

int z = (*x)-(*y);
return z;

As an output we are printing the address of ‘x’, the value of ‘x’ and the value of ‘*x.’ Printing ‘&x’ will give us the address of the pointer variable. However, printing ‘x’ will give us the address x in the main() function. This is because that is what this variable stores. Moreover, printing ‘*x’ will give us the value of ‘x’ in the main() function.

int Subtract(int* x, int* y){
    printf("Address of 'x' in Subtract = %d\n",&x);
    printf("Value in 'x' of Subtract (address of 'x' in main) = %d\n",x);
    printf("Value at address stored in 'x' of Subtract = %d\n",*x);
    int z = (*x)-(*y);
    return z;
}

After the compilation of the above code, you will get the following output.

Pointers as Function returns pic3

As you can see here, the address of ‘x’ in main is different than the address of ‘x’ in Subtract. The value of ‘x’ of Subtract which is the address of ‘x’ of main is equal to the first address that we printed. Using the address we printed the value of ‘x’ in the Subtract() which we set to ’10.’ Lastly, you can view the output which is 8 because we had passed the arguments 10 and 2 inside the Subtract() function hence we received an output of (10-2)=8.

Now let us have a brief look at the program again without any additional print statements that we added before.

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

int Subtract(int* x, int* y){
    int z = (*x)-(*y);
    return z;
}
int main() {
    int x =10;
    int y=2;
    printf("Address of 'x' in main: %d\n",&x);
    int z= Subtract(&x,&y);
    printf("Output: %d\n",z);
}

The Subtract() function returns the value ‘z’. In the main() method we are collecting this value ‘z’ in another variable which is ‘z’ of main().

Returning Address of a Local Variable

Now, let’s discuss what happens if we return the address of a local variable. This code is similar to the previous code except we are using the address of a local variable ‘z’ and trying to access it content inside the main function. But there is an issue with this code. Let’s see what is the issue.

int *Subtract(int* x, int* y){
    int z = (*x)-(*y);
    return &z;
}
int main() {
    int x =10;
    int y=2;
    int* ptr = Subtract(&x,&y);
    printf("Output: %d\n",*ptr);
}

Now we want to return a pointer to integer from the Subtract() function. We will return &z instead of z. Ampersand operator when put in front of a variable gives the us the address.

int *Subtract(int* x, int* y){
    int z = (*x)-(*y);
    return &z;
}

In the main() function we will have to collect this particular address so we will define a pointer variable. We have to print the value at the address being pointed to by this pointer variable.

 int* ptr = Subtract(&x,&y);
 printf("Output: %d\n",*ptr);

We modified the Subtract() function to return a pointer to an integer. This function is now returning a pointer to integer.

However, our program code will not compile on some compilers. We will get an error as shown below. This is because modern compliers do not allow a function to return address of a local variable. This is because when creating a local variable it gets allocated in the stack. After the function finishes, its gets cleared. Furthermore, some compilers may let you compile the code but throw a segmentation fault on run time.

Pointers as Function returns pic4

On GCC, you will get segmentation fault:

pointer as a function return in c

Till now we have covered basics and see how not to return pointer from a function. Now, let’s see an example to return a pointer from a function with proper method.

How to Return Pointer from a Function

Now the question is what to do to return the result of variable from a function. We can allocate a memory for that variable on heap memory segment and returns its address. Because anything that we allocate on heap remains there until we explicitly deallocate it.

You can learn about dynamic memory allocation here:

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

int* Subtract(int* x, int* y){
        int *z = (int*)malloc(sizeof(int));
        *z = (*x)-(*y);
        return z;
}
int main() {
    int x = 10;
    int y= 2;
    int *z = Subtract(&x,&y);
    printf("Output: %d\n",*z);
}

Output:

pointer as a function returns

You may like to read other pointers tutorials:

Leave a Comment