[Ace-users] Corrupt data after calling ACE_Vector<T>::resize

Karl-Heinz wind at itq.de
Wed Nov 14 06:49:38 CST 2007


8<----------8<----------8<----------8<----------8<----------8<----------8<----

    ACE VERSION: 5.5.8

    HOST MACHINE and OPERATING SYSTEM:
        PC, Windows XP, VC8

    TARGET MACHINE and OPERATING SYSTEM, if different from HOST:
    COMPILER NAME AND VERSION (AND PATCHLEVEL):

    THE $ACE_ROOT/ace/config.h FILE: config-win32.h, ACE_USES_WCHAR,
    _USE_32BIT_TIME_T 1

    THE $ACE_ROOT/include/makeinclude/platform_macros.GNU FILE:

    CONTENTS OF $ACE_ROOT/bin/MakeProjectCreator/config/
default.features
    (used by MPC when you generate your own makefiles): MFC=0

    AREA/CLASS/EXAMPLE AFFECTED:
    TAO/IIOP_Connector, TAO/IIOP_Connection_Handler, ACE_INET_Addr

    DOES THE PROBLEM AFFECT:
        COMPILATION? no
        LINKING? no
        EXECUTION? yes
        OTHER (please specify)?

    SYNOPSIS:
    Corrupt Data when enlarging ACE_Array_Base buffer after calling
resize

    DESCRIPTION:
    If an ACE_Vector is shrinked by calling the
ACE_Array_Base<T>::resize you
    will get corrupt data when the internal buffer is getting enlarged
during
    a later call to ACE_Vector::push_back. The problem resides in the
    ACE_Array_Base class:
    - resize shrinks the buffer by calling ACE_Array_Base<T>::size
which sets
      the member cur_size_ to new size (array_base.cpp 199).
    - if later calls to ACE_Vector::push_back cause the buffer the be
      enlarged again via ACE_Array<T>::size (vector_t.cpp 38) then not
all
      data is copied to the new buffer: array_base.cpp 173

    To sum it up: shrinking and enlarging using ACE_Array<T>::resize
could
    lead to corrupt data.

    REPEAT BY:


    SAMPLE FIX/WORKAROUND:
    cur_size_ is not changed when calling push_back or pop_back, but
    resize does: this leads to inconsistent members.




    Sample Program:

    #include <ace/OS.h>
    #include <ace/Vector_T.h>

int
ACE_TMAIN (int argc, ACE_TCHAR **argv)
{
    int ret = 0;

    ACE_Vector<int> Data;

    // we add Data (0x20 should be enough)
    for(int i=0; i<31; i++)
    {
        Data.push_back(1);
    }

    // Data.length_         = 31
    // Data.cur_size_       = 32
    // Data.curr_max_size   = 32

    // now we remove some elements from the end
    Data.resize(20, 0);

    // Data.length_         = 20
    // Data.cur_size_       = 20
    // Data.curr_max_size   = 32

    // now we add data to force the buffer to be resized
    for(int i=0; i<32; i++)
    {
        // when i is 12 (buffer will be enlarged)
        Data.push_back(2);
    }

    // Here you should watch the buffer in your memory window
    // 0-19 should be 1
    // 20 and above should be 2
    for(int i=0; i<Data.size(); i++)
    {
        // when i is 12 (buffer will be enlarged)
        ACE_DEBUG((LM_INFO, ACE_TEXT("%d\n"), Data[i] ));
    }
    // but you can see that the buffer is corrupt as only 20
(Data.cur_size_)
    // elements were copied when the buffer was enlarged

    return ret;
}




brgs KH



More information about the Ace-users mailing list