-2
#include <stdio.h>

int *sum_returning_pointer(int *x, int *y)
{
    // Call be reference
    int z = (*x) + (*y);
    return &z;
}

void main(int *argc, char *argv[])
{
    int a = 1, b = 2;
    int *p = sum_returning_pointer(&a, &b);
    printf("Sum = %d\n", *p);
}

With the above function i'm trying to add up the two numbers which are passed as a reference to the called function and returning pointer pointing to the variable where sum is stored. But i'm getting weird error saying.

Error has occured.
Segmentation Fault.

What does this error mean? How can i achieve a solution ? Why does this error occurs ?

Surya Bhusal
  • 520
  • 2
  • 8
  • 28
  • 1
    z is a local variable and its scope ends when the function exits. Using it outside the scope invokes UB. The compiler should warn you about that – phuclv Oct 23 '21 at 16:57
  • 1
    You can't access the value of `z` after the function ends (it's undefined behavior). – sj95126 Oct 23 '21 at 16:57
  • I was referring to this vide. https://youtu.be/zuegQmMdy8M?t=10383 where it worked fine. Any clues ?? – Surya Bhusal Oct 23 '21 at 17:00
  • 1
    It may *happen* to work in some cases, but it's undefined behavior, which means no particular result can be assumed. – sj95126 Oct 23 '21 at 17:01
  • 1
    I can't believe that video's top comment says "Best explanation on pointers ever" when it encourages undefined behavior. – sj95126 Oct 23 '21 at 17:09
  • @sbhusal123: One possible outcome of undefined behavior is that code behaves as expected. Another possible outcome is garbled output, corrupted data, or a runtime error. This example is not only poorly written, it’s also a *horrible* demonstration of why pointers are useful. – John Bode Oct 23 '21 at 18:34
  • @sbhusal123 stop using online tutorials and youtube for learning. Most of them are very bad. Read a good book instead: [The Definitive C Book Guide and List](https://stackoverflow.com/q/562303/995714). Probably because no experts watch such videos, it's still there without any comments pointing out the serious error – phuclv Oct 24 '21 at 01:37

2 Answers2

0

In main function z is not accessible that's why it is showing undefined behavior. You can declare z as a global variable like

#include <stdio.h>
int z =0;
int * sum_returning_pointer(int *x, int *y)
{
// Call be reference
z = (*x) + (*y);
 return &z;
 }

  void main(int *argc, char *argv[])
  {

   int a = 1, b = 2;
   int *p = sum_returning_pointer(&a, &b);
   printf("Sum = %d\n", *p);
   }
0

The problem is not how to dereference but how to assure that the pointer is valid. In your code the address of a local variable is returned. This lifetime of this variable ends when program returns from the function. Dereferencing this pointer after that invokes Undefined Behavior.

Note, that typically small objects like int should be returned by value.

There are 3 generic strategies of returning a pointer to the result from a function.

  1. (IMO, the best) Let the caller handle the lifetime.
int *foo(const int *x, const int *y, int *z) {
  *z = *x + *y;
  return z;
}

Usage:

int x = 1, y = 2, z;
int *res = foo(&x, &y, &z);
  1. Use dynamic storage
int *foo(const int *x, const int *y) {
  int *z = malloc(sizeof *z);
  if (!z) {
    // complain
    return NULL;
  }
  *z = *x + *y;
  return z;
}

This solution tends to be very slow and error prone because the caller is responsible for freeing result.

  1. Use static.
int *foo(const int *x, const int *y) {
  static int z;
  z = *x + *y;
  return &z;
}

Works well because lifetime of a static variable extends for the whole execution of the program.

The main issue is that the object pointed by the pointer will change with every invocation of foo. That is especially dangerous for multi-threaded applications.

tstanisl
  • 13,520
  • 2
  • 25
  • 40