Solved

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

Posted on 2011-03-14
22
2,002 Views
Last Modified: 2012-05-11
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 Crash screen shot.
0
Comment
Question by:davinder101
  • 9
  • 7
  • 6
22 Comments
 
LVL 32

Expert Comment

by:phoffric
ID: 35127114
>> memset(objS2, 0, sizeof(S2));
Only use memset on a POD-struct; otherwise you are likely destroying internal implementation of non-POD data types.
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35127163
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.
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35127178
>> objS2.varS1.push_back();

what argument did you give for push_back( arg )?
     http://www.cplusplus.com/reference/stl/vector/push_back/
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35127221
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
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35127285
Additional information of interest:
     http://www.parashift.com/c++-faq-lite/intrinsic-types.html#faq-26.7
0
 

Author Comment

by:davinder101
ID: 35127291
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.
0
 
LVL 32

Expert Comment

by:sarabande
ID: 35127304
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
0
 

Author Comment

by:davinder101
ID: 35127351
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.
0
 
LVL 32

Expert Comment

by:sarabande
ID: 35127355
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
0
 

Author Comment

by:davinder101
ID: 35127407
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);
}
0
 
LVL 32

Expert Comment

by:sarabande
ID: 35127442
can you post the file?

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

Sara
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 32

Expert Comment

by:sarabande
ID: 35127469
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
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35127611
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.
0
 

Author Comment

by:davinder101
ID: 35127669
This is unicode character set and this working fine in vs2005.
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35127712
>> 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.
0
 

Author Comment

by:davinder101
ID: 35127733
i did not change any thing in my vs2008 code. This is same code which i am using in vs2005.
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35127970
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).
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35127986
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.
0
 
LVL 32

Accepted Solution

by:
sarabande earned 500 total points
ID: 35128057
the stl has changed from VS2005 to VS2008.

while VS2005 didn't have a problem with the (very bad) zero initialization you made, the stl in vs2008 has. you cannot port to vs2008 without accepting that as a fact. it is good that you can correct that bug now which also in VS2005 could have lead to subtile errors.

as told the problem is with objS2. can you check each of the occurrence of that variable in your code and make sure that you don't write to that variable (memcpy, memset, read, ...).

Sara
0
 

Author Comment

by:davinder101
ID: 35136192
Thank you Sara, as you said i did and my application is running without crashes.
0
 

Author Closing Comment

by:davinder101
ID: 35136195
Thank you.
0
 
LVL 32

Expert Comment

by:sarabande
ID: 35136621
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
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now