Kuntal Basu
Kuntal Basu

Reputation: 830

returning address in C

Why this code is giving unexpected output.

int * func(int *xp)
{
    int y = 10 + *xp;
    return (&y);
}
void main()
{
    int x = 10;
    int *xp = func(&x);
    printf("%d\n", x);
    printf("%d\n", *xp);
}

expected output:

10
20

Real Output:

10
1074194112

Upvotes: 1

Views: 206

Answers (6)

William
William

Reputation: 91

As everyone mentioned already, you are trying to return the address of a temporary variable. What nobody has mentioned is the easiest solution. Cast the variable as static inside the function. This makes it remain in memory for the entirety of the program.

int * func(int *xp)
{
    static int y;
    y = 10 + *xp;
    return (&y);
}
void main()
{
    int x = 10;
    int *xp = func(&x);
    printf("%d\n", x);
    printf("%d\n", *xp);
}

This works as expected. Of course there are better ways to go about this, but this is the simplest solution if you indeed want to declare a variable inside the scope of a function, and return it's address. Keep in mind, every time this function is called, it modifies y, it doesn't give you a copy.

Upvotes: 0

phihag
phihag

Reputation: 287755

Returning the address of a local variable and then derefencing it causes undefined behavior.

Since the printf calls use the same memory (stack) region that func uses, they overwrite the stack frame of func with their own internal variables and function arguments.

To solve this problem, allocate memory on the heap with malloc:

int* func (int *xp) {
  int* res = malloc(sizeof(int));
  if (!res) {
    perror('Cannot allocate memory in func');
    exit(1);
  }
  *res = 10 + *xp;
  return res;
}

Don't forget to free it:

int main(void) {
    int x = 10;
    int *xp = func(&x);
    printf("%d\n", x);
    printf("%d\n", *xp);
    free(xp);
    return 0;
}

Upvotes: 1

NPE
NPE

Reputation: 500217

You are returning a pointer to a variable (y) that goes out of scope the moment you leave func. This is undefined behaviour.

It is not entirely clear what you're trying to achieve, but there are several ways to fix this:

  1. return the int by value;
  2. modify *xp in place and don't return anything;
  3. take an additional int* parameter and store the result in there (again returning void);
  4. allocate memory on the heap using malloc or new and return that (the caller would be responsible for correctly freeing that memory).

It is impossible to say which of the above are applicable to your problem without knowing the broader context.

Lastly, main() should return int (thanks @pmg for spotting this). This is not related to the problem you're having but is worthing pointing out.

Upvotes: 10

npclaudiu
npclaudiu

Reputation: 2441

func should look like this:

// C++
int* func(int* xp)
{
    int* y = new int;
    *y = 10 + *xp;
    return y;
}

Upvotes: 1

wormsparty
wormsparty

Reputation: 2499

< real_life_example >

Imagine you put an apple on the table. You then write down it's position on a piece of paper. Later, someone comes and takes the apple. The position on the piece of paper now makes no sense.

< /real_life_example >

Upvotes: 2

Aamir
Aamir

Reputation: 15546

Because y goes out of scope when function returns. Remember, y was declared on the stack. This is an undefined behavior.

Upvotes: 2

Related Questions