vector<CMyClass> push_back() loops on destroy because of incorrect element size. OK in VC6 
Author Message
 vector<CMyClass> push_back() loops on destroy because of incorrect element size. OK in VC6

I have a problem with a vector push_back() that goes into a loop on
inserting the second element. The destroy loop fails because the size of the
skip of the pointer goes over the _Last pointer.

As a test, I have a class declaration so:

// forward reference
class CBoat;

class CBoatListInfo {
public:
    struct BoatInfoItem {
        const TCHAR* (CBoat::*pTextFun)() const;// extract col item text
    };
    vector<BoatInfoItem> boatInfoItems;// one for each column

Quote:
};

I create an instance of the class and pass it to a test routine (at this
point CBoat is undefined) but the compiler is happy with the forward
reference for the pointer to member function.

void CTestNetView::OnEditTest()
{
    CBoatListInfo bli;
    Test(bli);

Quote:
}

Inside the test routine I add instances of the BoatInfoItem struct to the
vector within the class by the following:

int
Test(CBoatListInfo& boatListInfo)
{
    CBoatListInfo::BoatInfoItem bii;
    bii.pTextFun = NULL;

    for(int iCol = 0; iCol < 2; ++iCol) {
        boatListInfo.boatInfoItems.push_back(bii);
    }
    return 0;

Quote:
}

In this routine, the CBoat definition is available through the "boat.h"
header file. It's do-nothing definition is as follows:

class CBoat {
public:
    const TCHAR* Sail() const { return _T(""); }

Quote:
};

In the test, I never make use of this function.

When I trace through the push_back(), the second time around it has to
allocate space for two elements and destroy the first element. In this
destructor in xmemory:200 is this code:

template<class _Ty,
 class _Alloc> inline
 void _Destroy_range(_Ty *_First, _Ty *_Last, _Alloc& _Al,
  _Nonscalar_ptr_iterator_tag)
 { // destroy [_First, _Last), arbitrary type
 for (; _First != _Last; ++_First)
  _Al.destroy(_First);
 }

_First has a value of 0x00337898, _Last has a value of 0x0033789c and
sizeof(*_First) has a value of 0x10. Once round the loop gives _First a
value of 0x003378b8 which is after _Last so the loop never ends! From the
increment from the ++_First of 0x20, the size of the vector<CBoatListInfo>
is incorrect.

If the compiler needs to see the CBoat class defined before it can figure
out the size of the pointer to member function it should give me an error
message. However, I don't see why it needs more than a forward reference.

This compiled and ran with no problem under VC6.

Ed
--
Edward E.L. Mitchell
www.racesail.org
(239)415-7039
6707 Daniel Court
Fort Myers, FL 33908



Tue, 17 May 2005 02:00:54 GMT  
 vector<CMyClass> push_back() loops on destroy because of incorrect element size. OK in VC6
Edward,
Can you send me a repro?
I will take a look.
Thank you,
Bobby Mattappally
Microsoft VC++/C# Team

This posting is provided "AS IS" with no warranties, and confers no rights.

--------------------

Quote:

>Subject: vector<CMyClass> push_back() loops on destroy because of

incorrect element size. OK in VC6
Quote:

>I have a problem with a vector push_back() that goes into a loop on
>inserting the second element. The destroy loop fails because the size of
the
>skip of the pointer goes over the _Last pointer.

>As a test, I have a class declaration so:

>// forward reference
>class CBoat;

>class CBoatListInfo {
>public:
>    struct BoatInfoItem {
>        const TCHAR* (CBoat::*pTextFun)() const;// extract col item text
>    };
>    vector<BoatInfoItem> boatInfoItems;// one for each column
>};

>I create an instance of the class and pass it to a test routine (at this
>point CBoat is undefined) but the compiler is happy with the forward
>reference for the pointer to member function.

>void CTestNetView::OnEditTest()
>{
>    CBoatListInfo bli;
>    Test(bli);
>}

>Inside the test routine I add instances of the BoatInfoItem struct to the
>vector within the class by the following:

>int
>Test(CBoatListInfo& boatListInfo)
>{
>    CBoatListInfo::BoatInfoItem bii;
>    bii.pTextFun = NULL;

>    for(int iCol = 0; iCol < 2; ++iCol) {
>        boatListInfo.boatInfoItems.push_back(bii);
>    }
>    return 0;
>}

>In this routine, the CBoat definition is available through the "boat.h"
>header file. It's do-nothing definition is as follows:

>class CBoat {
>public:
>    const TCHAR* Sail() const { return _T(""); }
>};

>In the test, I never make use of this function.

>When I trace through the push_back(), the second time around it has to
>allocate space for two elements and destroy the first element. In this
>destructor in xmemory:200 is this code:

>template<class _Ty,
> class _Alloc> inline
> void _Destroy_range(_Ty *_First, _Ty *_Last, _Alloc& _Al,
>  _Nonscalar_ptr_iterator_tag)
> { // destroy [_First, _Last), arbitrary type
> for (; _First != _Last; ++_First)
>  _Al.destroy(_First);
> }

>_First has a value of 0x00337898, _Last has a value of 0x0033789c and
>sizeof(*_First) has a value of 0x10. Once round the loop gives _First a
>value of 0x003378b8 which is after _Last so the loop never ends! From the
>increment from the ++_First of 0x20, the size of the vector<CBoatListInfo>
>is incorrect.

>If the compiler needs to see the CBoat class defined before it can figure
>out the size of the pointer to member function it should give me an error
>message. However, I don't see why it needs more than a forward reference.

>This compiled and ran with no problem under VC6.

>Ed
>--
>Edward E.L. Mitchell
>www.racesail.org
>(239)415-7039
>6707 Daniel Court
>Fort Myers, FL 33908



Mon, 23 May 2005 03:08:29 GMT  
 vector<CMyClass> push_back() loops on destroy because of incorrect element size. OK in VC6
Edward,

Thanks for sending the project to me.

Quote:
>>If the compiler needs to see the CBoat class defined before it can figure
>>out the size of the pointer to member function it should give me an error
>>message. However, I don't see why it needs more than a forward reference.

The size of the pointer to a member could vary depending upon the member
pointer representation used in the class.
If you use only a forward reference you should use the "full_generality"
option instead of the default "best_case" .
Please see the documentation for /vmg and /vmb compiler option:

In this case CBoatListInfo::BoatInfoItem had different size in the two
modules.

I added the following pragma to "test.h"

#pragma pointers_to_members( full_generality, single_inheritance )

and the code works fine.

In this case,  since there is no cross refernce involved, just include the
full definition for CBoat  class and you should be fine.

Hope this helps.

Thank you,
Bobby Mattappally
Microsoft VC++/C# Team

This posting is provided "AS IS" with no warranties, and confers no rights.

--------------------

Quote:
>X-Tomcat-ID: 517116528

>MIME-Version: 1.0
>Content-Type: text/plain
>Content-Transfer-Encoding: 7bit

>Organization: Microsoft
>Date: Wed, 04 Dec 2002 19:08:29 GMT
>Subject: RE: vector<CMyClass> push_back() loops on destroy because of

incorrect element size. OK in VC6
Quote:

>Edward,
>Can you send me a repro?
>I will take a look.
>Thank you,
>Bobby Mattappally
>Microsoft VC++/C# Team

>This posting is provided "AS IS" with no warranties, and confers no rights.

>--------------------

>>Subject: vector<CMyClass> push_back() loops on destroy because of
>incorrect element size. OK in VC6

>>I have a problem with a vector push_back() that goes into a loop on
>>inserting the second element. The destroy loop fails because the size of
>the
>>skip of the pointer goes over the _Last pointer.

>>As a test, I have a class declaration so:

>>// forward reference
>>class CBoat;

>>class CBoatListInfo {
>>public:
>>    struct BoatInfoItem {
>>        const TCHAR* (CBoat::*pTextFun)() const;// extract col item text
>>    };
>>    vector<BoatInfoItem> boatInfoItems;// one for each column
>>};

>>I create an instance of the class and pass it to a test routine (at this
>>point CBoat is undefined) but the compiler is happy with the forward
>>reference for the pointer to member function.

>>void CTestNetView::OnEditTest()
>>{
>>    CBoatListInfo bli;
>>    Test(bli);
>>}

>>Inside the test routine I add instances of the BoatInfoItem struct to the
>>vector within the class by the following:

>>int
>>Test(CBoatListInfo& boatListInfo)
>>{
>>    CBoatListInfo::BoatInfoItem bii;
>>    bii.pTextFun = NULL;

>>    for(int iCol = 0; iCol < 2; ++iCol) {
>>        boatListInfo.boatInfoItems.push_back(bii);
>>    }
>>    return 0;
>>}

>>In this routine, the CBoat definition is available through the "boat.h"
>>header file. It's do-nothing definition is as follows:

>>class CBoat {
>>public:
>>    const TCHAR* Sail() const { return _T(""); }
>>};

>>In the test, I never make use of this function.

>>When I trace through the push_back(), the second time around it has to
>>allocate space for two elements and destroy the first element. In this
>>destructor in xmemory:200 is this code:

>>template<class _Ty,
>> class _Alloc> inline
>> void _Destroy_range(_Ty *_First, _Ty *_Last, _Alloc& _Al,
>>  _Nonscalar_ptr_iterator_tag)
>> { // destroy [_First, _Last), arbitrary type
>> for (; _First != _Last; ++_First)
>>  _Al.destroy(_First);
>> }

>>_First has a value of 0x00337898, _Last has a value of 0x0033789c and
>>sizeof(*_First) has a value of 0x10. Once round the loop gives _First a
>>value of 0x003378b8 which is after _Last so the loop never ends! From the
>>increment from the ++_First of 0x20, the size of the vector<CBoatListInfo>
>>is incorrect.

>>If the compiler needs to see the CBoat class defined before it can figure
>>out the size of the pointer to member function it should give me an error
>>message. However, I don't see why it needs more than a forward reference.

>>This compiled and ran with no problem under VC6.

>>Ed
>>--
>>Edward E.L. Mitchell
>>www.racesail.org
>>(239)415-7039
>>6707 Daniel Court
>>Fort Myers, FL 33908



Mon, 23 May 2005 07:17:55 GMT  
 vector<CMyClass> push_back() loops on destroy because of incorrect element size. OK in VC6
Bobby,

Thanks for the feedback.

It seems that I am correct that the C++ standard allows for a pointer to
member function to be defined based only on a forward reference. It's
apparently for efficiciency's sake within VisualStudio C++ that the size can
change.

Isn't this a compiler bug though?  I have a standard conforming program that
worked under VC6 and now fails quietly in VC7. It would be nice if the
compiler gave some sort of a warning instead of failing in an infinite loop
when the code happens to be executed.

I tried the global /vmg switch since the help says that though less
efficient,  it would guarantee that the pointers to member functions would
be the same size. This obviously has other problems since all the menu items
are greyed out (standard MFC do-nothing test project) when this /vmg switch
is used and I recompile everything. Something odd is happening here so I
left this alone.

I've got around the immediate problem by using the #pragma that you suggest.
I put it in each of the header files that has a forward reference to the
class. Hopefully I can find all the places where I am using a pointer to
member function!

Ed



Quote:
> Edward,

> Thanks for sending the project to me.

> >>If the compiler needs to see the CBoat class defined before it can
figure
> >>out the size of the pointer to member function it should give me an
error
> >>message. However, I don't see why it needs more than a forward
reference.

> The size of the pointer to a member could vary depending upon the member
> pointer representation used in the class.
> If you use only a forward reference you should use the "full_generality"
> option instead of the default "best_case" .
> Please see the documentation for /vmg and /vmb compiler option:

> In this case CBoatListInfo::BoatInfoItem had different size in the two
> modules.

> I added the following pragma to "test.h"

> #pragma pointers_to_members( full_generality, single_inheritance )

> and the code works fine.

> In this case,  since there is no cross refernce involved, just include the
> full definition for CBoat  class and you should be fine.

> Hope this helps.

> Thank you,
> Bobby Mattappally
> Microsoft VC++/C# Team



Tue, 24 May 2005 02:30:03 GMT  
 vector<CMyClass> push_back() loops on destroy because of incorrect element size. OK in VC6

Quote:
>Isn't this a compiler bug though?  I have a standard conforming program
that
>worked under VC6 and now fails quietly in VC7.
> It would be nice if the
>compiler gave some sort of a warning instead of failing in an infinite loop
>when the code happens to be executed.

This is kind of similar to using different packing  of structures (/Zp or
#pragma pack ) in two modules.
Compiler/linker  doesn't warn in that case also.
I had made a suggestion to the dev  team about doing some kind of detection
for  packing problems.
I will forward this also to them.

Hope this helps.

Thank you,
Bobby Mattappally
Microsoft VC++/C# Team

This posting is provided "AS IS" with no warranties, and confers no rights.

--------------------

Quote:
>Subject: Re: vector<CMyClass> push_back() loops on destroy because of

incorrect element size. OK in VC6

Quote:
>Date: Thu, 5 Dec 2002 13:30:03 -0500
>Bobby,

>Thanks for the feedback.

>It seems that I am correct that the C++ standard allows for a pointer to
>member function to be defined based only on a forward reference. It's
>apparently for efficiciency's sake within VisualStudio C++ that the size
can
>change.

>Isn't this a compiler bug though?  I have a standard conforming program
that
>worked under VC6 and now fails quietly in VC7. It would be nice if the
>compiler gave some sort of a warning instead of failing in an infinite loop
>when the code happens to be executed.

>I tried the global /vmg switch since the help says that though less
>efficient,  it would guarantee that the pointers to member functions would
>be the same size. This obviously has other problems since all the menu
items
>are greyed out (standard MFC do-nothing test project) when this /vmg switch
>is used and I recompile everything. Something odd is happening here so I
>left this alone.

>I've got around the immediate problem by using the #pragma that you
suggest.
>I put it in each of the header files that has a forward reference to the
>class. Hopefully I can find all the places where I am using a pointer to
>member function!

>Ed



>> Edward,

>> Thanks for sending the project to me.

>> >>If the compiler needs to see the CBoat class defined before it can
>figure
>> >>out the size of the pointer to member function it should give me an
>error
>> >>message. However, I don't see why it needs more than a forward
>reference.

>> The size of the pointer to a member could vary depending upon the member
>> pointer representation used in the class.
>> If you use only a forward reference you should use the "full_generality"
>> option instead of the default "best_case" .
>> Please see the documentation for /vmg and /vmb compiler option:

>> In this case CBoatListInfo::BoatInfoItem had different size in the two
>> modules.

>> I added the following pragma to "test.h"

>> #pragma pointers_to_members( full_generality, single_inheritance )

>> and the code works fine.

>> In this case,  since there is no cross refernce involved, just include
the
>> full definition for CBoat  class and you should be fine.

>> Hope this helps.

>> Thank you,
>> Bobby Mattappally
>> Microsoft VC++/C# Team



Tue, 24 May 2005 11:11:23 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. list<CMyclass* >, unable to retrieve push_back()'ed

2. <<<<<<<Parsing help, please>>>>>>>>

3. File Format conversion, ascii freeform -->.csv <-->.wk1<-->dbf<-->?HELP

4. <<<>>>Need C code advice with functions and sorting.<<<>>>

5. <><><>HELP<><><> PCMCIA Motorola Montana 33.6

6. >>>Windows Service<<<

7. incorrect <rpcndr.h> version

8. how to destroy CComObjectGlobal<T>?

9. vector<vector<T>> doesn't work

10. STL map<string, IHTMLElement*> Elements

11. C++ STL Vector push_back method

12. C++ STL Vector push_back method

 

 
Powered by phpBB® Forum Software