0

Is my function has undefined behavior? Becouse there is local variable c, so its in automatic location so it will be destruct after execution of function? (end of scope)

int* calculate(int* a,int* b)
{
  int c=(*a)+(*b);  //local variable c
  return &c;
}
int main()
{
  int a=12;
  int b=23;
  int* ptr=calculate(&a,&b);
  std::cout<<*ptr<<endl;
}
Vito Carleone
  • 157
  • 3
  • 8
  • 1
    Yes it is UB. You are returning the address of a local variable. – juanchopanza Oct 21 '13 at 07:18
  • ok thanks what about without using c variable, just return (*a)+(*b); that will be undefined behaviour too? becouse there is not a local variable. – Vito Carleone Oct 21 '13 at 07:24
  • 1
    @DonCarleone: Actually there still is a local object (unnamed). But if you change the return type to `int` then it'll get copied and everything's fine. – Lightness Races in Orbit Oct 21 '13 at 07:28
  • If you remove the return type of "Calculate" to "int", then the value of "int c" which is local to "Calculate" will be copied to the variable, say "int x" which is collecting the return value of "Calculate". Thus, nothing undefined here. – Abhineet Oct 21 '13 at 07:33

2 Answers2

2

Yes, returning a pointer to a temporary local object and dereferencing that is undefined behavior.

Because after exiting the function calculate, that object goes out of scope and automatically will be destroyed, then the provided pointer, points to an invalid address and it's a dangling pointer. After that, you can use dereference and use it (for example: *ptr).

In your case, you can use a normal variable, remove those *:

int calculate(int *a, int *b)
{
  int c = (*a)+(*b);
  return c;
}

since you have nothing reasonable to pass them by pointer, it's better to remove more *:

int calculate(int a, int b)
{
  int c = a + b;
  return c;
}
masoud
  • 55,379
  • 16
  • 141
  • 208
  • ok thanks what about without using c variable, just return (*a)+(*b); that will be undefined behaviour too? becouse there is not a local variable. – Vito Carleone Oct 21 '13 at 07:26
  • @DonCarleone: `(*a)+(*b)` is not a pointer and you can not return it, it makes compile error. I've updated my answer, look at it again. – masoud Oct 21 '13 at 07:32
  • **points to an invalid address and it's a dangling pointer** wrong! there is no any dangling pointer! everyone says dangling pointer but its not such thing like dangling here. This c will destroyed so it means it no exist it means if its in a memory place with address it wont be there any more memory place so How we can call this unknown place address we general say NULL. So in Main ptr pointer value will be NOADDRESS it will be NULL. – Vito Carleone Nov 09 '13 at 00:59
  • @VitoCarleone: No. It's a dangling pointer indeed. When `c` be destroyed it still has the address of destroyed object in memory. Then `ptr` has this address. After destroying something compiler will not set it to null automatically. You can test it your self, check if `ptr` is null or not. – masoud Nov 09 '13 at 09:12
  • yes it is dangling pointer ;) i try to be sure that you know the subject :P – Vito Carleone Nov 09 '13 at 11:40
1

You can pass an int declared in the main, to calculate, like this::

void calculate(int* a,int* b, int* c)
{
  *c=(*a)+(*b); 
  return ;
}
int main()
{
  int a=12;
  int b=23;
  int c=0;
  calculate(&a,&b,&c);
  std::cout<<c<<endl;
  return 0;
}

The much more simpler way is::

int Calculate( int a, int b )
{
    return a+b ;
}
int main( void )
{
    int a=12, b=23;
    std::cout<<Calculate(a,b)<<endl;
    return 0;
}
Abhineet
  • 5,320
  • 1
  • 25
  • 43