Question

Why I is the output of the following code 10 and not an error? Isn't object2 a dangling pointer?

#include <iostream>
using namespace std;


int *method()
{
  int object = 10;
  return &object;
}


int main()
{
    int *object2 = method();

    cout << *object2;
}

Thanks!

Was it helpful?

Solution

Why I is the output of the following code 10 and not an error?

Because undefined behaviour is undefined. Specifically, nothing happens to overwrite the memory that used to contain object, so the value hasn't changed by the time you dereference the dangling pointer. If you try printing it a second time, you might see something different. Or not - undefined behaviour could do anything.

Isn't object2 a dangling pointer?

Yes. Dereferencing a dangling (or otherwise invalid) pointer gives undefined behaviour, so don't do that.

You should be able to avoid this by enabling compiler warnings; on GCC, the specific warning is enabled by -Wreturn-local-addr, but I strongly suggest you build with at least -Wall -Wextra -Werror to catch as many potential mistakes as possible.

OTHER TIPS

You do get a dangling pointer, in that it points to memory which is no longer allocated, and your dereference of it constitutes undefined behaviour.

The behaviour in this case happens to be: that the address is still valid, and hasn't been overwritten with anything else.

The compiler doesn't waste time writing zeroes over everything just in case you dereference a dangling pointer, but you can verify that it's really dangling by running with valgrind or similar, or by performing some other function calls in between retrieving the pointer and dereferencing it.

The code you've written is not an error, it's undefined behavior.

Both gcc and valgrind will check you out on this.

main.cpp: In function 'int* method()':
main.cpp:7:7: warning: address of local variable 'object' returned [-Wreturn-local-addr]
   int object = 10;
       ^
main.cpp: In function 'int main()':
main.cpp:16:21: warning: 'object' is used uninitialized in this function [-Wuninitialized]
     cout << *object2;

==22403== Conditional jump or move depends on uninitialised value(s)
==22403==    at 0x4C99D61: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (locale_facets.tcc:870)
==22403==    by 0x4C9A2FC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (locale_facets.h:2475)
==22403==    by 0x4CA5C1D: std::ostream& std::ostream::_M_insert<long>(long) (locale_facets.h:2336)
==22403==    by 0x4007A3: main
==22403==

etc... It is a programming error, not a compiler error. As others have stated, it is undefined behavior. The compiler is not required to diagnose undefined behavior. That's why you should turn warnings on.

It is undefined behaviour, g++ give a warning about it:

main.cpp:7:7: warning: address of local variable 'object' returned [-Wreturn-local-addr]    
   int object = 10;

http://coliru.stacked-crooked.com/a/ca3950756cefa9b7

and you can get whatever result, correct value, 0 -> infinity, also crashes etc. its called Undefined Behaviour.


If you use g++, I would recomend adding : -Werror=return-local-addr, then you will get a nice error instead of warning:

main.cpp:7:7: error: address of local variable 'object' returned [-Werror=return-local-addr]
   int object = 10;

not sure, since which version you can do this - I suppose this is quite new addition to g++

Why I is the output of the following code 10 and not an error?

You are returning address of function temporary variable. Dereference such an address after function returned is undefined behavior. This means strange things may happen and you can see it by yourself.

Isn't object2 a dangling pointer?

Yes, it is.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top