Solved

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

Posted on 2011-03-14
22
2,117 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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 34

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 34

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 34

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
 
LVL 34

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 34

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 34

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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

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…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

738 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