-1

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!

Deanie
  • 2,316
  • 2
  • 19
  • 35
Jacob Krieg
  • 2,834
  • 15
  • 68
  • 140
  • I'd say this had so many dups that it's difficult to count them all. – Martin James Mar 11 '14 at 18:24
  • 'cos you happen to be lucky – Ed Heal Mar 11 '14 at 18:26
  • Sometimes, undefined behavior happens to not format your hard drive, by chance. If you call some other functions between method() and cout, 42 may be printed, instead of 10. – manuell Mar 11 '14 at 18:27
  • I like this description: “When the compiler encounters [a given undefined construct] it is legal for it to make demons fly out of your nose” from http://www.catb.org/jargon/html/N/nasal-demons.html – marcinj Mar 11 '14 at 18:36

6 Answers6

2

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.

Useless
  • 64,155
  • 6
  • 88
  • 132
2

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.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
1

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

SingleNegationElimination
  • 151,563
  • 33
  • 264
  • 304
  • 1
    Many consider UB an error. It's just not the nice kind of error that reliably announces itself. –  Mar 11 '14 at 18:27
1

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.

1

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++

marcinj
  • 48,511
  • 9
  • 79
  • 100
1

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.

4pie0
  • 29,204
  • 9
  • 82
  • 118