Re: Problem with Vectors and STL/ATL in Visual C++ 2005

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Ulrich

Many many thanks :-)

Your solution worked. I understand that the code was broken previously and
I'm just glad I know where we are going wrong now thanks to you. I'm no
expert on STL and I guess I better start reading up on it.

Once again, many many thanks.

Colin

"Ulrich Eckhardt" <eckhardt@xxxxxxxxxxxxxx> wrote in message
news:7lkji3-duu.ln1@xxxxxxxxxxxxxxxxxxxxxxxxx
Colin J Paterson wrote:
iNumElements = m_Tables.GetSize();
pEnumerator->Init(m_Tables.GetAddress(0),
m_Tables.GetAddress(iNumElements), NULL, AtlFlagNoCopy);
[...]
If I make the changes you say I get a Automation Error in Visual Basic
when it returns the empty variant. The get address function seems to
deliberately return past the the end of the vector as described in the
MSDN for CComEnumImpl::Init.

Okay, then you know for the future what to document there. Anyhow,
comparing
this:

if(IsEmpty() || (iIndex < 0) || iIndex > m_vector.size())
{
return &m_emptyVariant;
}

and this:

if( iIndex < m_vector.size())
return &m_vector[iIndex].m_Variant;

return &m_emptyVariant;

The above variant is definitively broken C++ code. Nothing about external
requirements will ever change that. I repeat, you must not call vector's
operator[] with a value equal to or greater than its size. Period, no
discussion here.

Now, for the enumerator's Init(), you still need two pointers that
represent
the start and past-the-end of the sequence. If the sequence is empty, you
could return NULL or some other dummy value for index=0 and index=size.
Otherwise, you could return the address of the first element
(vector::front()) plus the index. I would consider creating a get_range()
function instead, because the habit of letting a one-off index slip
through
is really bad and confusing. At the very least, it deserves being
documented.

I stress, this worked fine in VC6

Let me repeat what I wrote:

This seems to work in Visual C++ 6 but in 2005 it throws a subscript
out of range error? Any ideas why?

Simply because its standardlibrary is better, in debug mode it features
a
checked implementation like STLport that catches several errors where
the
standard just shrugs and says "undefined behaviour, no diagnostic
required". The code was broken all along though.


Just for completeness, there are two additional alternatives you could
use:

1. Move the computation of the past-the-end pointer to outside the array
class:
pEnumerator->Init(m_Tables.GetAddress(0),
m_Tables.GetAddress(0)+iNumElements,
NULL, AtlFlagNoCopy);

This doesn't cater for an empty container though, but I think that's an
error all along, which might deserve special handling anyway.

2. Always maintain an additional object in the array. You would then
insert
new elements before that last element instead of using push_back() etc,
but
you would have the guarantee that the contained array is never empty and
that the past-the-end element exists and is accessible. You would have to
adjust methods that use the size of the vector accordingly.

Uli



.



Relevant Pages

  • Re: Problem with Vectors and STL/ATL in Visual C++ 2005
    ... when it returns the empty variant. ... Move the computation of the past-the-end pointer to outside the array ... Always maintain an additional object in the array. ...
    (microsoft.public.vc.stl)
  • Re: How to copy non-contiguous columns to a text file
    ... a single output string could theoretically exceed the limits of the String data type. ... Unlikely as all that might seem, I refer to design algorithms that do not break when expected limits are exceeded. ... I vaguely remember that some other applications requires the empty line at the end when they import the file. ... The last line, then, should be the Record.Count since the first record is elementof the array. ...
    (microsoft.public.excel)
  • Re: Macros in php
    ... From the PHP manual for empty: ... "The following things are considered to be empty: ... array() ... practice in PHP. ...
    (comp.lang.php)
  • Re: Index from TM
    ... And the intersection of my chosen cell and the A1:A9 range was an ... These arguments can be either defined, empty or omitted. ... The array_ argument has been defined, ... If the indexed array was C22:C25 the relative sequential positions would be ...
    (microsoft.public.excel.worksheet.functions)
  • Re: Index from TM
    ... Microsoft Excel MVP ... And the intersection of my chosen cell and the A1:A9 range was an ... These arguments can be either defined, empty or omitted. ... The array_ argument has been defined, ...
    (microsoft.public.excel.worksheet.functions)