-1

I was hoping someone here could make sense of what I think could be a MSVC 2010 bug.

I have this code (as part of a much larger project):

namespace MyNamespace{

class Foo{
   //snip
   QPointer<MyNamespace::Baz> :: x;
};

class Baz{
   //snip
};

//snip
Foo::Bar(){
   x = new MyNamespace::Baz();
   ThisFunctionWillSegfaultIfXIsNull(x);
   //snip
}

Again, keep in mind, this is part of a much larger project, involving cmake, qt, and a whole host of other exciting things.

I've been tracing through this with a debugger. When I compile this project in Debug mode, everything goes as expected. However, when I compile this as a Release project, x gains the value of 0x0000000000000000.

Also, when tracing through this in the MSVS debugger (still in release mode), a few interesting things happen:

  1. The constructor for Baz is in fact called, and "this" has a valid memory location inside of Baz's constructor.

  2. After returning from the constructor (back in Foo::Bar()), the value of this (presumably "Foo") is now THE SAME as the value of "this" inside of Baz's constructor (presumely "Baz").

  3. None of Foo's data appears to have been lost, even though it just apparently changed memory addresses.

  4. "This" (as Foo) somehow magically grows a new data member of type MyNamespace::Baz, that contains all of the correct data that was assigned during the constructor.

So apparently compiler optimization is making something extremely mystical occur. Again, this only seems to occur in Release mode, which makes me think that A) the optimizer is making a difference and B) makes it difficult for me to get further information on what is actually happening.

Has anyone seen this before? What is happening here? How can I get my next function to stop segfaulting because X is null?

Rizier123
  • 58,877
  • 16
  • 101
  • 156
Hounddog
  • 385
  • 1
  • 10
  • 2
    Personnally, when the debugger is completely wrong (especially in release mode), I use `printf` for precise debugging. – Synxis Sep 06 '12 at 17:55
  • I'll give that a shot, but I can't seem to figure out where standard out is going in this madhouse project. Maybe I could get Qt messageboxes or something to work...hmm...... – Hounddog Sep 06 '12 at 18:35
  • Debugging release builds will never work right, but usually won't tell you that (and might sort of follow along, just enough that you don't notice). That goes double, at least, for trying to see the values of variables. The actual problem here, however, is that a) your function segfaults if `x` is null and b) neither the function nor the code around it *test* for that condition. Fix that and you won't have a problem. – ssube Sep 06 '12 at 19:33
  • @peachykeen Yeah you were right, my specific problem posed in this this question was simply a symptom of the MSVS debugger lying to me about the value of variables. – Hounddog Sep 07 '12 at 13:56
  • as far as I have read QPointer can only be used on QObjects, have you tried using a shared or unique ptr instead? It is not clear from your code what kind of object Baz is, looks like a regular class. – AndersK Mar 02 '16 at 05:55

1 Answers1

1

The problem is somewhere else. Besides the debugger playing tricks on you (as it often happens in release mode), new can never return NULL. If the allocation fails, it will throw an exception, but it never returns NULL.

You can check this with some debug statements:

if (x)
   std::cout << "x is not NULL";
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • 4
    Actually `new (std::nothrow) T` can return NULL, but this is not the case. – Greg Sep 06 '12 at 18:02
  • Right I am aware new can never return NULL, but that doesn't really change what I'm seeing in the debugger. Putting in if(x) ... else ... Causes some other wonky behavior. Like I said, I think it's an optimizer issue. I'm tracing through the assembly now. – Hounddog Sep 06 '12 at 18:34