Link to home
Start Free TrialLog in
Avatar of davinder101
davinder101

asked on

std::vector clear() and push_back() functions crashes in vs2008

Hi,
I am having MFC application in visual studio 2008.
I define an structure example-S1 having some members and another structure example-S2 having S1 as vector member.
std::vector clear() and push_back() functions crashes in vs2008 and the same code working fine in visual studio 2005.

Example-
struct S1
{
   int i;
};
struct S2
{
  int j;
  vector<S1> varS1;
};

S2 objS2;
memset(objS2, 0, sizeof(S2));
objS2.varS1.clear();   //Application crashes at this point. But this code runs fine in visual studio 2005.

If i comment memset fuction is run fine untill it reach push_back() function and at point this it crashes.

Crashes at this point if i comment memset function.
objS2.varS1.push_back();

Please Help me out.
Thanks User generated image
Avatar of phoffric
phoffric

>> memset(objS2, 0, sizeof(S2));
Only use memset on a POD-struct; otherwise you are likely destroying internal implementation of non-POD data types.
Even if you have a struct with only POD type members, if another class or struct is derived from it (so now it is a base class), then you should not memset the struct as it hold vtable information that you will wipe out.

Using memset on a non-POD-struct, as you discovered, is certainly not portable.
>> objS2.varS1.push_back();

what argument did you give for push_back( arg )?
     http://www.cplusplus.com/reference/stl/vector/push_back/
Oh, BTW, I realize that you were not cut and pasting but if you do a memset, then you need an pointer for the first argument, like
     memset( & objS2, 0, sizeof(S2));
       http://www.cplusplus.com/reference/clibrary/cstring/memset/

re: the push_back argument - it should be an object of type S1
Avatar of davinder101

ASKER

Thanks for your responses.
I commented memset in vs2008 and it will not crashes on clear() function but it crashes on push_back() function and the same lines working fine in vs2005.

In actual my structure are-

struct S1
{
      BYTE  _Bv;
      TCHAR _tP1[MAX_PATH];
        TCHAR _tP2[MAX_PATH];
      BOOL  _bv;
};

struct S2
{
      BYTE            _bx;
      vector<S1>      varS1;
      TCHAR            csP1[MAX_PATH];
      TCHAR            csP2[512];
      BYTE            _bFlag;      
};

S2 objS2;
//memset(objS2, 0, sizeof(S2)); I commented this line.
objS2.varS1.clear();  

S1 temp;
initialization of temp members.
objS2.varS1.push_back(temp);

why all these lines without commenting memset working fine in vs2005 and not in vs2008.
Is i have do some setting or any thing else.
Please help me out.
to add to above:

std::vector is a class type of standard template library (STL). all classes of stl are well-defined and part of c++ standard. that in any way means those classes have a proper constructor which does all needed initialization and you must not do any basic memory operations on those objects.

the reason why it crashes in vs2008 is that they have three internal members

      pointer _Myfirst;      // pointer to beginning of array
      pointer _Mylast;      // pointer to current end of sequence
      pointer _Myend;      // pointer to end of array

where the _Mylast is not NULL (but 0xcccccccc) after construction.

i would assume in vs2005 they used a zero initialisation for all members.

Sara
i already used  memset(& objS2, 0, sizeof(S2)); in my program but while posting here i made a mistake.i mentioned the arguments i passed in push_back.
Please tell me how to avoid crash in vs2008 beacuse i shifted my code to vs2008.
the below code doesn't crash in vs2008:

struct S1
{
      BYTE  _Bv;
      TCHAR _tP1[MAX_PATH];
        TCHAR _tP2[MAX_PATH];
      BOOL  _bv;
};

struct S2
{
      BYTE            _bx;
      vector<S1>      varS1;
      TCHAR            csP1[MAX_PATH];
      TCHAR            csP2[512];
      BYTE            _bFlag;      
};

int main(int argc, char *argv[])
{

    S2 objS2;
    //memset(objS2, 0, sizeof(S2)); I commented this line.
    objS2.varS1.clear();  

    S1 temp;
    // initialization of temp members.
    temp._bv = true;
    temp._Bv = '\0';
    strcpy(temp._tP1, "Hello World");
    strcpy(temp._tP2, "Nice To have");

    objS2.varS1.push_back(temp);


    return 0; 
}

Open in new window



can you show your 'initialisations' of temp variable.
Sara
I am filling S1 temp members from reading an file.

//csFileName is name of an file.
if(ff.Open(csFileName, CFile::modeRead))
{
    UINT nBRead = ff.Read(&temp, sizeof(S1));
    if(nBRead>0)            
      objS2.varS1.push_back(temp);
}
can you post the file?

what is the sizeof(TCHAR) ? do you have UNICODE or MULTIBYTE character set?

Sara
note, the ff.Read would not copy more than sizeof(S1) bytes to S1. so even if there is garbage read, the push_back will not crash.

i would assume you still have some memcpy, memset or binary read to objS2 which has destroyed internal pointers or sizes.

Sara
Instead of having us guessing as to what may be causing your crash, why not ask a new question posting a short program where you can illustrate the crashing problem. Each code post that you are making here is changing the nature of your original question.

BTW - on VS 2010, sizeof(TCHAR) is 2.
This is unicode character set and this working fine in vs2005.
>> this working fine in vs2005
but not fine in vs2008 -- that means that somewhere in your code you have some code that has undefined behavior. That means that from one compiler release to another, the code may or may not function as previously done. We both gave possible reasons why one worked and another did not.

Instead of having us guessing as to what may be causing your crash, why not ask a new question posting a short program where you can illustrate the crashing problem. Each code post that you are making here is changing the nature of your original question.
i did not change any thing in my vs2008 code. This is same code which i am using in vs2005.
In my experience it is quite common for code to stop working when moving from one compiler to another. The cause in these many cases was code that results in undefined behavior. A simple example to illustrate this is a set/use issue. In a version that functionally worked, an autovariable was used without it being set. When we upgraded the compiler, the program crashed. We set the variable and all was good (except for the 1000 other little problems).
I believe that we answered the question in your OP. Now, if you could ask a new question where you post a short program that illustrates your crash, then we will be able to identify the problem. If you find that your short programs do not crash, then that is likely indicative of a problem in your larger code set.
ASKER CERTIFIED SOLUTION
Avatar of sarabande
sarabande
Flag of Luxembourg image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you Sara, as you said i did and my application is running without crashes.
Thank you.
you are welcome :)

the problem with memcpy, memset and CFile::Read is that they have a void pointer as argument what means they accept any pointer. so the type safety of C++ was bypassed. other interfaces - for example std::ifstream::read - have a char* pointer instead of void* what requires a cast for many cases but make clear that you do a raw binary copy and not a safe logical assignment.

Sara