Wallace
Wallace

Reputation: 651

Why This Code Gives Segmentation Fault

Below code snippet is run on linux, and it reports Segmentation Fault (Core Dump). I found error happens when the destructor is called, but can't figure out why. Can anybody help explain this?

    class TStringPair{
    public:
        TStringPair(){
            memset(this, 0, sizeof(TStringPair));
        }


        string a;
        string b;
    };

    int main (int argc, char* argv[])
    {
        TStringPair test;
        return 0;
    }

Upvotes: 2

Views: 141

Answers (2)

Jeremy Friesner
Jeremy Friesner

Reputation: 73091

Just before the body of your TStringPair constructor runs, the std::string class's default constructor gets called (automatically) for each of your two string member-objects.

The std::string default constructor sets the contents of those two objects to their correct state. What is that correct state? We don't know (not without looking through the STL source code, anyway), but that's okay, because we don't have to know -- we can rely on the std::string class implementers to do the right thing.

However, after those constructors run, your memset goes through and overwrites (whatever info they wrote) with zero-bytes... now those string objects are in a corrupted state, so it's no surprise that you get a crash when their destructor runs and encounters that corruption.

Upvotes: 2

Qaz
Qaz

Reputation: 61920

That memset ruins your class quite literally. The memory of a std::string (as well as many other C++ classes) should not be filled with zeros, but you fill both.

To illustrate why this is a bad idea, consider a std::string having a pointer to the actual characters. Oops, instead of pointing to a null string, it now points to 0. There are other reasons why zeroing out a non-C object is bad, but they aren't quite as relevant to this example.

I imagine removing the memset and putting nothing in its place would give the exact result you were going for.

Upvotes: 4

Related Questions