From: DanB on

Giovanni,
Oliver,
David,

I forgot to say thank you...

Thank you, Dan.

From: Giovanni Dicanio on
"DanB" <abc(a)some.net> ha scritto nel messaggio
news:iXcin.22$3D3.16(a)newsfe19.iad...

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

Since VS2005 (VC8) they added a new STL feature called "iterator debugging":

http://msdn.microsoft.com/en-us/library/aa985939(VS.80).aspx

This feature is available only in debug builds; it's on by default, but it
can be turned off with a line like this e.g. in StdAfx.h:

// Switch off iterator debugging in debug builds:
#define HAS_ITERATOR_DEBUGGING 0

In general, this feature helps you identify some subtle bugs. So it could be
the case that you have some bug in your code; but the bug was hidden in
VC7.1, but thanks to iterator debugging, it was identified by newer VC9
(VS2008).

In release build the iterator debugging feature is off (and can't be turned
on), so this could be the reason why your code "works fine" in release
version. Actually, it could be that in release version the bug is hidden.
So, I would suggest that you fix the code in debug build; the iterator
debugging would probably like to say you something about a bug in your
code...

Giovanni


From: Giovanni Dicanio on
You're welcome.

Giovanni


"DanB" <abc(a)some.net> ha scritto nel messaggio
news:p%cin.23$3D3.14(a)newsfe19.iad...
>
> Giovanni,
> Oliver,
> David,
>
> I forgot to say thank you...
>
> Thank you, Dan.
>
From: Giovanni Dicanio on
"DanB" <abc(a)some.net> ha scritto nel messaggio
news:iXcin.22$3D3.16(a)newsfe19.iad...

>>> class HE_XML_EXT_CLASS XMLNODESET
>>> {
>>> private:
>>> std::vector<TiXmlNode*> set;
>>> ...
> [...]
> 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.

If XMLNODESET contains only vector and other copiable classes, then the
default copy ctor and operator= produced by the VC++ compiler should be just
fine.
(And if the XMLNODESET class has an ownership semantics for the pointers
stored in the vector, then vector<shared_ptr<>> should be just fine; if
there is no ownership semantics, then the raw pointers should work.)

So, if you don't have a particular need to write custom copy ctor and
operator= implementations, just don't do that, and see what happens.

If you need to write a custom implementation of one of them, then you
typically want to implement also the other one (and in general, a [virtual]
destructor, too.)
In general, there is this "rule of three" in C++:

http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)

But, the KISS rule is still valid: so don't write custom boilerplate copy
code if you don't have to, IMHO.

Giovanni


From: DanB on
Hi Giovanni,

I took a break and put some new porch lights up with my wife.

Now I have new information. By doing some extra tracing into vector, I
noticed two different assignment operators for the first and second
call. I asked myself how that could be? So then I saw I had two vector
headers open!??!

In the first call:
XMLNODESET nodeset= xml.GetNodeSet( "//*/test" );

I land in the 2003 7.1 header <vector>. And here:

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

I'm in the 9.0 header <vector>.

Both these lines are in the same function of the CView test app not far
from each other, so I'm baffled. The tracing stays in the right places
in either header and all the trace info is correct in both files. I
don't know how the compiler could use two of the same headers to compile
a cpp file, but it sure looks like it did. If this is possible, (and I
don't believe it), I can see that this debug info would not really exist
that gets cleaned up in the second assignment.

Twilight Zone music starts here for me...


BTW, I have the whole solution, 7.1 version, here:

http://lakeweb.net/MFC/downloads/xml.zip

Thanks much, Dan.