1

I'm on a big C++/stl mystery with Visual Studio 2010 :

I push back an object to a list, and when I access to it, I get partially un-initialized data. Here is a very minimalist sample of code that produce this behavior :

#include <map>
#include <list>
#include <iostream>

using namespace std ;

struct Foo
    {
    Foo ( int x , int y ) ;
    friend ostream & operator<< ( ostream & out , const Foo & foo ) ;
    int x,y ;
    };

Foo::Foo ( int x , int y ) : x(x),y(y) 
    { 
    cout << "construct " << *this << endl ;
    }

ostream & operator<< ( ostream & out , const Foo & foo )   
    { 
    out << "Foo( " << foo.x << "," << foo.y << " )[" << &foo << "]"; 
    return out ;
    }

int main ()
    {
    list<Foo> foolist ;
    for ( int x = 7 ; x < 12 ; x++ )
        foolist.push_back( Foo( x,x*x )) ;

    for ( list<Foo>::iterator i = foolist.begin() ; i != foolist.end() ; ++i )
        cout << *i << endl ;
    }

And here is the output :

construct Foo( 7,49 )[003FFE94]
construct Foo( 8,64 )[003FFE94]
construct Foo( 9,81 )[003FFE94]
construct Foo( 10,100 )[003FFE94]
construct Foo( 11,121 )[003FFE94]
Foo( 7,-33686019 )[00224D98]
Foo( 8,-33686019 )[00224DE0]
Foo( 9,-33686019 )[00225048]
Foo( 10,-33686019 )[00225090]
Foo( 11,-33686019 )[002250D8]

I think that 003FFE94 is the address of a temporary object which is copied at its final location within the list. But the copy seems to be partial : only the first member x is copied.

For information, the same code works well when compiled with gcc :

construct Foo( 7,49 )[0x28ff20]
construct Foo( 8,64 )[0x28ff20]
construct Foo( 9,81 )[0x28ff20]
construct Foo( 10,100 )[0x28ff20]
construct Foo( 11,121 )[0x28ff20]
Foo( 7,49 )[0x976f40]
Foo( 8,64 )[0x976f58]
Foo( 9,81 )[0x976f70]
Foo( 10,100 )[0x976f88]
Foo( 11,121 )[0x976fa0]

So, if someone understands what Visual is doing with my list, and what I should do to make it work... Thanks in advance !

Hadrien

Captain'Flam
  • 479
  • 4
  • 12
  • Cannot reproduce on different environnments including VS 2017. Your code looks OK to me. – Jabberwocky Jan 12 '18 at 14:35
  • Do you have the same issue if you write this: `for (int x = 7; x < 12; x++) { Foo f(x, x*x); foolist.push_back(f); } ?` – Jabberwocky Jan 12 '18 at 14:39
  • 2
    `-33686019` is 0xFDFDFDFD, i.e. your compiler thinks `Foo` is shorter than it actually is. Do you have struct `Foo` defined elsewhere in the same project? – rustyx Jan 12 '18 at 14:48
  • @RustyX good point for the `0xfdfdfdfd` which is the value used by the debug libraries to fill freed memory. But the OPs code is a self containing example, so there shouldn't be any other `foo` defined elsewhere. – Jabberwocky Jan 12 '18 at 15:12
  • `0xfdfdfdfd` marks no mans land in Visual Studio. `0xFEEEFEEE` is freed heap memory. https://stackoverflow.com/a/127404/487892 – drescherjm Jan 12 '18 at 15:25
  • @drescherjm you're right, I mixed them up. Thanks for the correction. – Jabberwocky Jan 12 '18 at 15:31
  • I only remembered because I had looked at it yesterday for a different question here.. – drescherjm Jan 12 '18 at 15:32
  • What happens if you rename your member variables to, for example, `x_` and `y_`? – Phil Brubaker Jan 12 '18 at 16:14
  • It works as it should using latest-and-greatest VC++ 2017 (15.5) As a workaround, try using an automatic variable for the Foo(x,x*x) when you push_back. – Jive Dadson Jan 12 '18 at 17:16

0 Answers0