Board index » cppbuilder » STL problem

STL problem


2005-08-13 11:30:01 PM
cppbuilder13
I'm getting compilation errors in a program which I can not understand
even after several hours of checking. I have condensed the code into
the following:
#include <windows.h>
#include <dir.h>
#include <vector>
#pragma hdrstop
WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR
lpCmdLine, int nCmdShow)
{
struct sxTest
{
int iToken;
unsigned char fbStatus;
char szName[MAXPATH];
std::vector<int>vecInt; // [C++ Error]
};
sxTest Test;
std::vector<int>vecNumbers2; // [C++ Error]
return 0;
}
I get the following errors:
[C++ Error] MainTest.cpp(12): E2316 'vector' is not a member of 'std'
[C++ Error] MainTest.cpp(12): E2040 Declaration terminated incorrectly
[C++ Error] MainTest.cpp(15): E2316 'vector' is not a member of 'std'
[C++ Error] MainTest.cpp(15): E2188 Expression syntax
Can anyone please give me a hint on where the problem can be. It's
hidden from me!
I use WinXP SP2, BCB Pro v6.
Thanks in advace
Anders
 
 

Re:STL problem

Hi all,
I get an error with the following code:
std::vector<int>aList;
std::vector<int>bList;
aList.resize(10, 5);
bList = aList;
The error is reported by CodeGuard when I step over the last line. Any
idea why this is so and whether it should happen?
BTW, using Builder 5 and the error message is underflow in pointer
arithmetics. It stops in vector.cc while calling va.deallocate().
This is not a great deal as the program works fine when CodeGuard is
disabled, but to find some other problems I'd like to enable CodeGuard
and as I use quite a few vectors it stops very often.
Regards
Matthias
 

Re:STL problem

"mbaessler" < XXXX@XXXXX.COM >wrote in message
Quote
Hi all,

I get an error with the following code:

std::vector<int>aList;
std::vector<int>bList;

aList.resize(10, 5);
bList = aList;

The error is reported by CodeGuard when I step over the last line. Any
idea why this is so and whether it should happen?

BTW, using Builder 5 and the error message is underflow in pointer
arithmetics. It stops in vector.cc while calling va.deallocate().
There is a bug in BCB5 (Rogue Wave) for
std::vector's assignment operator. Someone
from TeamB (Chris, I think) posted a patch but
I've lost the link. You can try googling it or
maybe someone here has the link.
 

{smallsort}

Re:STL problem

mbaessler < XXXX@XXXXX.COM >writes:
Quote
I get an error with the following code:

std::vector<int>aList;
std::vector<int>bList;

aList.resize(10, 5);
bList = aList;

The error is reported by CodeGuard when I step over the last line. Any
idea why this is so and whether it should happen?
I think this is a bug in the RogueWave implementation of the STL that
shipped with BCB5.
Quote
BTW, using Builder 5 and the error message is underflow in pointer
arithmetics. It stops in vector.cc while calling va.deallocate().
This is old code and my memory isn't fresh, but I think I remember
looking into this way back when, and found that they're doing some
pointer arithmetic with pointers that have been deleted (to calculate
a distance between some addresses.) If this is indeed the problem,
you can safely ignore it, because the calcluated distance would be the
same whether it was done before the memory was deleted or after
(though the standard doesn't allow such arithmetic on invalid
pointers, as some platforms may cause hardware to trap.)
Quote
This is not a great deal as the program works fine when CodeGuard is
disabled, but to find some other problems I'd like to enable
CodeGuard and as I use quite a few vectors it stops very often.
I think I posted a patch (my own, unoffical and unsanctioned patch) to
this too, and maybe you can find it in the google archive if you are
interested. Then again, I may have fixed something else instead.
It's hard to remember with certainty. :)
--
Chris (TeamB);
 

Re:STL problem

"Chris Uzdavinis (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote
mbaessler < XXXX@XXXXX.COM >writes:
I think I posted a patch (my own, unoffical and unsanctioned patch) to
this too, and maybe you can find it in the google archive if you are
interested. Then again, I may have fixed something else instead.
It's hard to remember with certainty. :)
I was fairly sure that your patch fixed a bug with
assignments in std::vector. I looked for the link
and couldn't find it but it's been a while since
I used BCB5.
 

Re:STL problem

Duane Hebert wrote:
Quote
I was fairly sure that your patch fixed a bug with
assignments in std::vector. I looked for the link
and couldn't find it but it's been a while since
I used BCB5.
groups.google.com/group/borland.public.cppbuilder.language/msg/6868b6c1095b98ae&
tinyurl.com/8amf4
Looks like the problem is in resize.
--
Gillmer J. Derge [TeamB]
 

Re:STL problem

"Gillmer J. Derge [TeamB]" < XXXX@XXXXX.COM >wrote in message
groups.google.com/group/borland.public.cppbuilder.language/msg/6868b6c1095b98ae&
Quote
tinyurl.com/8amf4

Looks like the problem is in resize.
That's the one that I was referring to. It sounds
like the OP's problem as for me it showed up
in assigning vectors. Chris's patch fixed it for me.
Hopefully it will for the OP as well.
Thanks.
 

Re:STL problem

Quote
That's the one that I was referring to. It sounds
like the OP's problem as for me it showed up
in assigning vectors. Chris's patch fixed it for me.
Hopefully it will for the OP as well.

Thanks.
No, unforunately that didn't do it.
I read Chris' article and tried to patch the code, but it seems that
my copy is already patched (Update 1, Build 12.34). The file vector.cc
contained the lines of the patch with a remark
// RW_BUG: Fix for bts-78394
I don't know if this relates to the patch, though.
Now, I looked at the code and after doing the following, the problem
disappears:
aList.resize(10, 5);
bList.resize(10); //add this (size may be equal or greater!)
bList = aList; //no error anymore
The error occurs in the assignment operator during the call to
va.deallocate().
The code is:
__end_of_storage = uninitialized_copy(x.begin(), x.end(), tmp);
__destroy(__start, __finish);
va.deallocate(__start,__end_of_storage.data()-__start);
__start = tmp;
Just before calling va.deallocate() __start evalueates to NULL and
__end_of_storage.data() to 0x00d268f4, so pointer arithmetic should be
no problem and va.deallocate() simply calls the delete operator with
the first argument and deleting the null pointer should be fine.
But CodeGuard insists on the error. Strange though, it says
0x00000000 - 0x00d268f4
Thanks for your help
 

Re:STL problem

mbaessler wrote:
Quote
>That's the one that I was referring to. It sounds
>like the OP's problem as for me it showed up
>in assigning vectors. Chris's patch fixed it for me.
>Hopefully it will for the OP as well.
>
>Thanks.


No, unforunately that didn't do it.
I read Chris' article and tried to patch the code, but it seems that
my copy is already patched (Update 1, Build 12.34). The file vector.cc
contained the lines of the patch with a remark
// RW_BUG: Fix for bts-78394
I don't know if this relates to the patch, though.

Now, I looked at the code and after doing the following, the problem
disappears:
aList.resize(10, 5);
bList.resize(10); //add this (size may be equal or greater!)
bList = aList; //no error anymore

The error occurs in the assignment operator during the call to
va.deallocate().
The code is:
__end_of_storage = uninitialized_copy(x.begin(), x.end(), tmp);
__destroy(__start, __finish);
va.deallocate(__start,__end_of_storage.data()-__start);
__start = tmp;

Just before calling va.deallocate() __start evalueates to NULL and
__end_of_storage.data() to 0x00d268f4, so pointer arithmetic should be
no problem and va.deallocate() simply calls the delete operator with
the first argument and deleting the null pointer should be fine.
But CodeGuard insists on the error. Strange though, it says
0x00000000 - 0x00d268f4
Well, strictly speaking, performing pointer arithmetic on invalid
pointers is undefined behaviour (though generally it only ever does
anything strange when using error detectors like CodeGuard), so I assume
that's the problem. The solution is to patch vector either to initialize
__end_of_storage with a NULL pointer in the default constructor, or to
protect the above with:
if (__start)
va.deallocate(__start,__end_of_storage.data()-__start);
Tom
 

Re:STL problem

On Mon, 30 Jan 2006 16:04:58 +0000, Tom Widmer
< XXXX@XXXXX.COM >wrote:
Quote

Well, strictly speaking, performing pointer arithmetic on invalid
pointers is undefined behaviour (though generally it only ever does
anything strange when using error detectors like CodeGuard), so I assume
that's the problem. The solution is to patch vector either to initialize
__end_of_storage with a NULL pointer in the default constructor, or to
protect the above with:
if (__start)
va.deallocate(__start,__end_of_storage.data()-__start);

Tom
In this case there are no invalid pointers. __start is NULL and
__end_of_storage has been initialized AND the arithmetic is
__end_of_storage - _start, which is 0x00d268f4 - 0x00000000 and not
0x00000000 - 0x00d268f4.
I think I'll have to remember to first resize a vector before
assigning new values to it.
Thanks all.
 

Re:STL problem

mbaessler wrote:
Quote
On Mon, 30 Jan 2006 16:04:58 +0000, Tom Widmer
< XXXX@XXXXX.COM >wrote:

>Well, strictly speaking, performing pointer arithmetic on invalid
>pointers is undefined behaviour (though generally it only ever does
>anything strange when using error detectors like CodeGuard), so I assume
>that's the problem. The solution is to patch vector either to initialize
>__end_of_storage with a NULL pointer in the default constructor, or to
>protect the above with:
>if (__start)
>va.deallocate(__start,__end_of_storage.data()-__start);
>
>Tom

In this case there are no invalid pointers. __start is NULL and
__end_of_storage has been initialized AND the arithmetic is
__end_of_storage - _start, which is 0x00d268f4 - 0x00000000 and not
0x00000000 - 0x00d268f4.
So 0x00d268f4 is a value returned from allocator.allocate? I would have
expected an empty vector to have __end_of_storage contain a NULL
pointer, so how has it been initialized by the constructor? Note that
even accessing an uninitialized pointer (a type of invalid pointer) is
illegal, you can't copy it, read it, etc. and all you can do is assign a
valid pointer value to it.
Strictly speaking, both subtraction operations are illegal regardless of
whether data() is returning a valid pointer or not. You can only
subtract pointers that point into the same array or object. Certainly,
the code has undefined behaviour, so CodeGuard is quite right to
complain about it.
Tom
 

Re:STL problem

Tom Widmer < XXXX@XXXXX.COM >writes:
Quote
Well, strictly speaking, performing pointer arithmetic on invalid
pointers is undefined behaviour (though generally it only ever does
anything strange when using error detectors like CodeGuard), so I
assume that's the problem.
Strange coincidence: A thread about a different instance of this
problem (from the old days of Borland C++) has just been started over
in borland.public.cpp.borlandcpp ("stl code guard").
 

Re:STL problem

On Tue, 31 Jan 2006 20:00:10 +0100, XXXX@XXXXX.COM (Thomas Maeder
[TeamB]) wrote:
Quote
Strange coincidence: A thread about a different instance of this
problem (from the old days of Borland C++) has just been started over
in borland.public.cpp.borlandcpp ("stl code guard").
I've seen this and maybe the solution is similar. From what Tom said,
I assume the calculation for deallocate() uses invalid pointers, so I
avoid calculating the size with the classes own (and after the
__destroy() invalid) data (in fact the deallocate() method doesn't
even use the second parameter!).
template <class T, class Allocator>
vector<T,Allocator>& vector<T,Allocator>::operator= (const
vector<T,Allocator>& x)
{
if (&x == this) return *this;
if (x.size()>capacity())
{
__value_alloc_type va(__end_of_storage);
iterator tmp = va.allocate(x.end() - x.begin(),0);
#ifndef _RWSTD_NO_EXCEPTIONS
try {
__end_of_storage = uninitialized_copy(x.begin(), x.end(),
tmp);
} catch(...) {
va.deallocate(tmp,x.end()-x.begin());
throw;
}
#else
__end_of_storage = uninitialized_copy(x.begin(), x.end(), tmp);
#endif // _RWSTD_NO_EXCEPTIONS
__destroy(__start, __finish);
-->Change here (the second parameter in deallocate() is not used!)
//va.deallocate(__start,__end_of_storage.data()-__start);
va.deallocate(__start, 0);
__start = tmp;
A quick test with vectors of ints and structs (one and two
dimensional) worked well. Can anyone confirm that?
Regards
Matthias
 

Re:STL problem

Thomas Maeder [TeamB] wrote:
Quote
Tom Widmer < XXXX@XXXXX.COM >writes:


>Well, strictly speaking, performing pointer arithmetic on invalid
>pointers is undefined behaviour (though generally it only ever does
>anything strange when using error detectors like CodeGuard), so I
>assume that's the problem.


Strange coincidence: A thread about a different instance of this
problem (from the old days of Borland C++) has just been started over
in borland.public.cpp.borlandcpp ("stl code guard").
Hmm, interesting. It's quite interesting that behaviour as subtly
undefined as performing arithmetic with invalid pointers can trigger
CodeGuard, but that second thread seems to confirm it.
Tom