From: DanB on
Giovanni Dicanio wrote:
>
> I'm not sure that deep-copying the above 'set' data member is a good
> robust thing, because the pointers stored in the vector are copied.
> What is the semantics of 'set'? Does the XMLNODESET class "own" the
> pointed TiXmlNode's?
> In this case, I would prefer using something like:
>
> vector< shared_ptr< TiXmlNode > > set;

Hi Giovanni,
Sorry I didn't answer this directly. No, the XMLNODESET only borrows the
reference. The pointers are meaningless without the CXML mother ship.

Best, Dan.
From: Oliver Regenfelder on
Hello,

DanB wrote:
> XMLNODESET::XMLNODESET( XMLNODESET& inSet )

The XMLNODESET::XMLNODESET(const XMLNODESET& inSet).
has already been pointed out.

> {
> *this= inSet;
> }
>
> dec:
> class HE_XML_EXT_CLASS XMLNODESET
> {
> private:
> std::vector<TiXmlNode*> set;
> ...
> };
>
> The pointer to the vector is copied now where as in 7.1 it would do a
> deep copy of the vector.

You talk about a pointer to the vector but your code above declares a
vector as membervariable and not a "pointer to vector".

Best regards,

Oliver
From: Giovanni Dicanio on
"DanB" <abc(a)some.net> ha scritto nel messaggio
news:x9Yhn.5035$mn6.401(a)newsfe07.iad...

> class HE_XML_EXT_CLASS XMLNODESET
> {
> private:
> std::vector<TiXmlNode*> set;
> ...

One more thing comes in my mind: are you exporting this class using a DLL?
(i.e. Is the HE_XML_EXT_CLASS preprocessor macro hiding some
__declspec(dllexport/import)?)

If so, note that it is extremely fragile to export C++ classes (including
STL classes) at DLL boundaries.
If you do so, you must be sure that all the modules (the DLL(s) and the EXE)
are built with the same compiler version and with the same compiler
settings.

Giovanni


From: David Wilkinson on
DanB wrote:
>
> Well I finally bought the new 2008 VS. I'm moving carefully over as I
> have to keep a 7.1 build current. I'm moving my support first as I don't
> have to keep it updated. I started with that hexml project.
>
> When I get to this as a copy constructor:
>
> XMLNODESET::XMLNODESET( XMLNODESET& inSet )
> {
> *this= inSet;
> }

If you are invoking the default assignment operator, this should not compile,
because the default assignment operator would take "const XMLNODESET&" as
argument.

So I assume you must have your own assignment operator taking "XMLNODESET&" as
argument. What does it do?

The normal behavior of assignment operator is member-wise assignment and the
assignment operator of std::vector will copy the contents (which is just a
pointer here). I find it hard to believe that the behavior has changed between
VS7.1 and VS9.

--
David Wilkinson
Visual C++ MVP
From: DanB on
Giovanni Dicanio wrote:
> "DanB" <abc(a)some.net> ha scritto nel messaggio
> news:x9Yhn.5035$mn6.401(a)newsfe07.iad...
>
>> class HE_XML_EXT_CLASS XMLNODESET
>> {
>> private:
>> std::vector<TiXmlNode*> set;
>> ...
>
> One more thing comes in my mind: are you exporting this class using a DLL?
> (i.e. Is the HE_XML_EXT_CLASS preprocessor macro hiding some
> __declspec(dllexport/import)?)
>
> If so, note that it is extremely fragile to export C++ classes
> (including STL classes) at DLL boundaries.
> If you do so, you must be sure that all the modules (the DLL(s) and the
> EXE) are built with the same compiler version and with the same compiler
> settings.
>
Hi Giovanni,

Yes, it is a dll. It is built from scratch in the same solution as the
test app and all the settings look to be the same. (It is old test code
and why you don't see the _T macro around the test string.)

And after tracing though, (even in the disassembly), and thinking...
Maybe I should have posted a little more code.

XMLNODESET nodeset= xml.GetNodeSet( "//*/test" );

At this point it is fine, it is when I do a second assignment:

nodeset= xml.GetNodeSet( "//*/subStuff/testing[@type=1]" );

the vector of the nodeset gets messed. and I get an access violation
right here. But I found this in 'vector':

#if _HAS_ITERATOR_DEBUGGING
this->_Orphan_all();
#endif /* _HAS_ITERATOR_DEBUGGING */

So I compiled the release version of the solution and then it works fine.

From what I see, when I make the assignment where it crashed, it is
doing this tidy on my returned object. I think it was meant for the
XMLNODESET that went out of scope in GetNodeSet(...), but I don't know
anything for sure yet.

~~~
Oliver, sorry, wrong way of expressing the memory location, it turns out
they were not in the same memory location after all, I was
misinterpreting what I saw.

~~~
David,
Really, I am using the default and the compiler generates it for me and
it does compile without a warning much less an error. And it is looking
like this is a debug issue now.

--- No source file
-------------------------------------------------------------
....
XMLNODESET::operator=:
10029360 push ebp
10029361 mov ebp,esp
10029363 push ecx
10029364 mov dword ptr [ebp-4],0CCCCCCCCh
1002936B mov dword ptr [ebp-4],ecx
1002936E mov eax,dword ptr [this]
10029371 mov ecx,dword ptr [__that]
10029374 mov edx,dword ptr [ecx]
10029376 mov dword ptr [eax],edx
10029378 mov eax,dword ptr [this]
1002937B mov ecx,dword ptr [__that]
1002937E mov edx,dword ptr [ecx+4]
10029381 mov dword ptr [eax+4],edx
10029384 mov eax,dword ptr [__that]
10029387 add eax,8
1002938A push eax
1002938B mov ecx,dword ptr [this]
1002938E add ecx,8
10029391 call std::vector<TiXmlNode *,std::allocator<TiXmlNode
*> >::operator= (100209BAh)
10029396 mov eax,dword ptr [this]
10029399 add esp,4
1002939C cmp ebp,esp
1002939E call @ILT+5520(__RTC_CheckEsp) (10021595h)
100293A3 mov esp,ebp
100293A5 pop ebp
....