LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   C++: program crashes on exit on std::string destructor (https://www.linuxquestions.org/questions/programming-9/c-program-crashes-on-exit-on-std-string-destructor-834270/)

Accinson 09-24-2010 10:13 AM

C++: program crashes on exit on std::string destructor
 
Hi everybody,
i am wondering why the following simple code causes a segfault on exit,when the std::string destructor is called.

Quote:

#include <iostream>
#include <string>

using namespace std;

struct myStruct
{
int a;
string b;
int c;
};

int main()
{
myStruct st;
st.a=2;
st.c=4;
memset(&st,0,sizeof(myStruct));

cout << "Hello world!" << endl;
return 0;
}
I guess the memset messes with some internal std::string's data structures/pointers. I personally am anti-memset,and always avoid them,but i'm really curious to know this....

Why does it segfault?

neonsignal 09-24-2010 10:28 AM

The typical implementation of an STL object is to allocate space on the heap for the actual data. So if you zero the structure that contains the pointer to that data, you will get a segment violation when it tries to use the pointer (probably when it calls the destructor at the end of the program).

Anyway, in C++ you could have written a constructor inside your struct, rather than zeroing it externally.

Accinson 09-26-2010 04:16 PM

Thank you for the reply :-)

I have a further question,though....
The project i "inherited" makes a terribly large use of memset to zero of various structures. Replacing all of them is a daunting task, and, besides,i can't even do it for some of them,so i ask:

1)What about structures composed ONLY by native integral data types? I guess i can leave "their" memsets with no harm... Is it right?

2)What about structures with methods? Is it ok to memset them to zero?

neonsignal 09-26-2010 04:59 PM

Quote:

Originally Posted by Accinson (Post 4109676)
1)What about structures composed ONLY by native integral data types? I guess i can leave "their" memsets with no harm... Is it right?

Yes, this won't cause problems in a normal scenario. It is not very portable (for example, floating point representations might be different on other processors), but you could live with it.

You are correct in avoiding memset in typical applications, because such functions effectively break the strong type checking, which results in a whole class of potential bugs that the compiler cannot pick up at compile time.

Quote:

Originally Posted by Accinson (Post 4109676)
2)What about structures with methods? Is it ok to memset them to zero?

In most circumstances, adding methods does not affect the way the structure is represented in memory. C++ was designed this way, both for efficiency and to increase compatibility with C.

The only caveat is for virtual methods, because these are typically implemented using a vtable pointer at the beginning of the object (instance of a struct or class). This also applies if any objects in the parent hierarchy have a virtual method.

johnsfine 09-26-2010 05:24 PM

Quote:

Originally Posted by Accinson (Post 4107819)
I guess the memset messes with some internal std::string's data structures/pointers
...
Why does it segfault?

Do you need a more detailed answer than the one you gave yourself?

If so, you would need to look at the source code of the specific implementation of std::string.

Quote:

Originally Posted by Accinson (Post 4109676)
1)What about structures composed ONLY by native integral data types? I guess i can leave "their" memsets with no harm... Is it right?

I think you can go quite a bit wider than that. If no members of the struct have defined constructors (or have members of their own with defined constructors) then a memset as you described should not be able to do harm. Nothing should be assuming the unconstructed members would not be zero filled.

So ints, floats, pointers, etc. and substructures of those should all be OK.

I would have warned you about virtual methods in the class or any base class or any member or base class of member, etc. But neonsignal gave a good enough warning on that topic. Don't do any memset that would overwrite any object's vtable pointer.


All times are GMT -5. The time now is 10:42 PM.