-2

I've been given this piece of code:

 #include <stdio.h>
 #include <math.h>

 struct polar_coordinate{
   double theta;
   double r;
 };
 struct polar_coordinate * polar(double x, double y);

int main(void){
   double x = 2.0;
   double y = 3.0;
   struct polar_coordinate * pci;

   pci = polar(x,y);
   printf("The coordinate x = %.1f and y = %.1f is 
   in polar coordinates theta = %.2f and r = %.2f\n ",x,y,pci->theta,pci->r);
   }

struct polar_coordinate * polar(double x, double y){
   struct polar_coordinate pc;
   pc.r = sqrt(x*x + y*y);
   pc.theta = atan2(y,x);
   return &pc;
}

I am then told that the struct polar_coordinate * polar function has a bug, that I have to fix. I tried doing this by using:

 struct polar_coordinate * polar(double x, double y){
   struct polar_coordinate * pc;
   pc->r = sqrt(x*x + y*y);
   pc->theta = atan2(y,x);
   return pc;
}

The code can then compile but if I try to run it I get a segmentation fault 11. But I can't really see what should be wrong.

some_name
  • 389
  • 3
  • 17
  • 1
    `polar()` returns a pointer to a local variable, whose lifetime ends once the function returns. Increase your compiler warnings. – P.P Dec 08 '15 at 10:56
  • 2
    Possible duplicate of [returning a local variable from function in C](http://stackoverflow.com/questions/4824342/returning-a-local-variable-from-function-in-c) – dandan78 Dec 08 '15 at 10:57

4 Answers4

1

You are trying to return local variable so you are getting error of segmentation fault so allocate dynamic memory using malloc or calloc and free after use.

working code with changes....

#include <stdio.h>
#include <math.h>

struct polar_coordinate{
    double theta;
    double r;
};
struct polar_coordinate * polar(double x, double y);

int main(void){
    double x = 2.0;
    double y = 3.0;
    struct polar_coordinate * pci;

    pci = polar(x, y);
    printf("The coordinate x = %.1f and y = %.1f is in polar coordinates theta = %.2f and r = %.2f\n ",x,y,pci->theta,pci->r);

    if (pci)
        free(pci);  //free memory after use
}

struct polar_coordinate * polar(double x, double y){
    struct polar_coordinate *pc = malloc(sizeof (struct polar_coordinate)); //Dynamic memory allocation

    pc->r = sqrt(x*x + y*y);
    pc->theta = atan2(y, x);
    return pc;
}
Mohan
  • 1,871
  • 21
  • 34
0

In this function

struct polar_coordinate * polar(double x, double y){
   struct polar_coordinate pc;
   pc.r = sqrt(x*x + y*y);
   pc.theta = atan2(y,x);
   return &pc;
}

You are returning the address of a local variable, which will be destroyed when the function returns. And later in main() you are trying to access it

pc.r = sqrt(x*x + y*y);
pc.theta = atan2(y,x);
Haris
  • 12,120
  • 6
  • 43
  • 70
  • But what about when I use the rewritten function? – some_name Dec 08 '15 at 10:59
  • In the rewritten version, you've declared a pointer, but not made it point at anything. You either need to be `malloc()`ing some memory inside the function (and `free()`ing it after use) or passing in the address of a `polar_coordinate` structure for the function to initialise. – TripeHound Dec 08 '15 at 11:05
0

In the function struct polar_coordinate * polar(double x, double y) you are returning a local instance of polar_coordinate which will be destroyed at the end of the function scope.

You have to allocate your return variable before returning it.

Wicked
  • 126
  • 6
0

You are returning a pointer to a local variable which goes out of scope when the function returns. But your fix causes a segmentation fault because you are using an uninitialised pointer. Here are two ways you can deal with it (without passing an extra argument)

struct polar_coordinate *polar(double x, double y){
    struct polar_coordinate * pc;
    pc = malloc(sizeof (struct polar_coordinate));
    if (pc == NULL)
        exit(1);
    pc->r = sqrt(x*x + y*y);
    pc->theta = atan2(y,x);
    return pc;
}

This returns a memory pointer which the caller will have to free and without that, repetitive calls will cause a memory leak.

Another way is by using a static local variable.

struct polar_coordinate *polar(double x, double y){
    static struct polar_coordinate pc;
    pc.r = sqrt(x*x + y*y);
    pc.theta = atan2(y,x);
    return &pc;
}

The disadvantage of this method is that subsequent calls to the function overwrite the struct.

Weather Vane
  • 33,872
  • 7
  • 36
  • 56