CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    May 2010
    Posts
    83

    list: insert empty element

    Hi,


    i define a custom struct, which contains other custom structs.
    Then i define a stdc++ list of this struct.

    I now want to insert a totally empty instance of my custom struct into the list.

    This is what i do:

    [code]
    lists<custstruct> mylist;
    custstruct x;
    ZeroMemory(&x, sizeof(custstruct ));
    mylist.push_back(x);
    [\code]

    This works.

    However, it does require me to have an empty struct instance available at all times.
    Surely, there is an easier way of inserting an empty element?

  2. #2
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: list: insert empty element

    ZeroMemory() is not, in general, an appropriate means of "emptying" an object. For some objects it will work; for others, like std::string, it could cause a crash later.

    Instead, define your type's default constructor to set it to whatever state you'd like an "empty" object to have. Then, you can simply default-construct objects without worrying about how they're initialized:

    Code:
    lists<custstruct> mylist;
    mylist.push_back(custstruct());

  3. #3
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    Re: list: insert empty element

    Once you have done what Lindley suggests, you can also add the
    element at the time of construction.

    Code:
    list<custstruct> mylist(1);

  4. #4
    Join Date
    Oct 2008
    Posts
    1,456

    Re: list: insert empty element

    BTW, if custstruct is a POD then both Lindley's and Philip's code will work without a default constructor being defined, because both push_back(custstruct()) and the size_t list constructor value-initialize the new custstruct instance, effectively zeroing it.

  5. #5
    Join Date
    May 2010
    Posts
    83

    Re: list: insert empty element

    thanks!

    i guess i wasnt fully aware of structs having constructors...

    And you guys are of course totally right about ZeroMemory()-clearing an object, although it works in this case.

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: list: insert empty element

    Quote Originally Posted by felix1432 View Post
    thanks!

    i guess i wasnt fully aware of structs having constructors...
    There is no difference between a struct and a class in C++, except that

    1) the members default to public in a struct, and private in a class.

    2) When deriving from a struct, by default the derivation is public, for a class, the derivation is private.
    And you guys are of course totally right about ZeroMemory()-clearing an object,
    ZeroMemory() knows nothing about objects, since ZeroMemory() is a 'C'-based API function. ZeroMemory only knows about an address, and the number of bytes starting at the address to set to 0. So if your object contains a virtual function, you will be wiping out the v-table, causing your program to crash (assuming you're using a compiler that implements virtual functions using a v-table, and most do). That is not just a mere "clearing an object" -- that is making an object unusable.
    although it works in this case.
    Does it work because your program still runs, or works because your struct is POD? If it's the former, then that is no proof that what you are doing is working. A running program can have hidden bugs. If it's the latter (the struct is a POD struct), then ZeroMemory() will work.

    However, as soon as you introduce anything to that struct that would then make it non-POD, (a member that is non-POD, a user-defined copy constructor, etc.), then that ZeroMemory() instantly becomes a bug. You would then need to go through your source code and change all of those ZeroMemory() calls to proper calls to initialize the object. The compiler does not give you a warning or an error when you make this mistake.

    This is why when starting a new program using structs and types that can change during the lifetime of development, you should refrain from using 'C'-based functions to manipulate that struct/class. The struct may start out as POD, then you write a mountain of code with many calls to memset(), or memcpy(), or ZeroMemory(), or whatever C function, and then you decide to introduce a std::string to that struct. Then boom, your program has bugs all over when you run it (and again, the compiler will not tell you about this -- you find out at the worst time, and that is when your program fails in random parts of the application).

    Regards,

    Paul McKenzie

  7. #7
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: list: insert empty element

    Quote Originally Posted by felix1432 View Post
    , although it works in this case.
    I have real example of this causing a bug.

    One developer we had in my last job cleared a POD struct using 'memclr' in his code. It all worked fine until someone else added a std::string. It took some time to trace the weird bug back to the 'memclr' and erradicate it from the code.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  8. #8
    Join Date
    May 2010
    Posts
    83

    Re: list: insert empty element

    You are, ofcourse, right and it seems i`ve been overusing ZeroMemory() in the past.
    I am re-working and updating some old code to use std:: classes, which then doesnt allow me to use ZM anymore.
    But how would you zero-inizialize a class/struct with 25+ data members?

    Only solution there is imo:

    a1 = 0;
    a2 = 0;
    ...
    a25 = 0;

    which is quiet annoying to implement and maintain.

    There is no better way, i assume?

  9. #9
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: list: insert empty element

    If the struct is a POD type, you can zero-initialize it like this
    Code:
    struct A
    {
        int a1;
        // ...
        float a25;
    };
    
    int main()
    {
        A a = { 0 };
    }
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: list: insert empty element

    Quote Originally Posted by felix1432 View Post
    There is no better way, i assume?
    If the struct is non-POD, then write a constructor, and you only need to do it once.
    Code:
    #include <string>
    
    struct foo
    {
       int v1;
       int v2;
       double v3;
       long v4;
       std::string x;
       foo() : v1(0), v2(0), v3(0.0), v4(0) { }
    };
    
    int main()
    {
       foo f;  // this constructs a foo with
    }
    Regards,

    Paul McKenzie

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured