3

I have a struct that looks like this:

typedef struct {
    int a;
    //other fields
    string s1;
    string s2;
} strMyStruct;

In The following code, append() method will crash since the string object x1.s1 was not constructed.

strMyStruct x1;
memset(&x1, 0, sizeof(x1));
x1.a = 100
x1.s1.append("....");

I can do placement new to solve it like new (x1.s1) string;, but it's too cumbersome and I don't have total control on the structure of strMyStruct: someone may add another string as a field to this struct and start using it and hit the crash issue, until he remembers to do placement new trick.

Really hoping the string class can handle it properly when initialization is done by memset(&x1, 0, sizeof(x1));. Is there a trick on this?

8
  • 4
    Why do you need to use memset? Why not use a normal constructor? The line strMyStruct x1; is already initializing the strings. Commented May 22, 2015 at 18:50
  • Didn't use constructor since I don't have the control on the structure, it keeps changing: Other developer may add/remove fields in this struct at will. Don't have a problem with initializing until people started using "string" object as a field. Commented May 22, 2015 at 18:53
  • 1
    You don't generally need to typedef a struct in C++ (struct names are automatically a typename). Difference between 'struct' and 'typedef struct' in C++? Commented May 22, 2015 at 18:58
  • 1
    @codingFun You can't use memset() to initialize complex objects :-P ... Commented May 22, 2015 at 19:03
  • 1
    @codingFun but it was acceptable before It should never have been acceptable, regardless of the member types in the struct. In C++, always use proper C++ initialization techniques, even if the struct or class contains POD (simple) types as members. Commented May 22, 2015 at 19:13

2 Answers 2

7

You can use uniform initialization to default construct the object.

strMyStruct x1{};

This will default initialize the members of that object. The way you have it written, the variable is declared but not initialized. You can also use this syntax to value initialize your struct.

strMyStruct x2{5, "foo", "bar"};
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you @CoryKramer, it works! SO prevents me from accepting it now, will do it in a few minutes.
It's worth noting that the second example here depends on the order of declaration of the struct members. If they are moved around, or if new members are added or removed, the initialization may silently break.
@DBRalir, good point. The job of my code is to make sure all members are initialized (numerical members are initialized to be 0, string members are initialized to be empty string). So strMyStruct x1{}; will work for me in this case.
4
strMyStruct x1;

here x1.s1 is correctly constructed with empty string.

memset(&x1, 0, sizeof(x1));

at this place you have overwritten internal fields of x1.s1 - most probably seting to null pointer which was holding string buffer - but it depends on its implementation. You should be aware that using memset in such way is Undefined Behaviour - mostly casing crashes. But crash willnot happen here, at least yet.

x1.a = 100

thats fine

x1.s1.append("....");

and now you try to use x1.s1 which is in undefined state, this most probably will crash because internal data (pointer to memory buffer) is null. But you dont now, this might work - it depends on string implementation.

Finally your code can crash when x1.s1 will get destroyed.

You cannot use memset on non POD structures, and your struct is not such struct. So you are left with either using constructor for initializing your data, or universal initialization as in @CoryCramer answer.

1 Comment

Thanks @marcinj for the analysis. that's exactly what happened!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.