tags:

views:

298

answers:

4

Hey guys. I am working on fixing older code for my job. It is currently written in C++. They converted static allocation to dynamic but didn't edit the memsets/memcmp/memcpy. This is my first programming internship so bare with my newbe-like question.

The following code is in C, but I want to have it in C++ ( I read that malloc isn't good practice in C++). I have two scenarios: First, we have f created. Then you use &f in order to fill with zero. The second is a pointer *pf. I'm not sure how to set pf to all 0's like the previous example in C++.

Could you just do pf = new foo instead of malloc and then call memset(pf, 0, sizeof(foo))?

struct foo { ... } f;
memset( &f, 0, sizeof(f) );

//or

struct foo { ... } *pf;
pf = (struct foo*) malloc( sizeof(*pf) );
memset( pf, 0, sizeof(*pf) );
+2  A: 

Yes, that would work. However, I don't think malloc is necessarily bad practice, and I wouldn't change it just to change it. Of course, you should make sure you always match the allocation mechanisms properly (new->delete, malloc->free, etc.).

You could also add a constructor to the struct and use that to initialize the fields.

Matthew Flaschen
+3  A: 

Can you? Yes, probably. Should you? No.

While it will probably work, you're losing the state that the constructor has built for you. Adding to this, what happens when you decide to implement a subclass of this struct? Then you lose the advantage of reuseable code that C++ OOP offers.

What you ought to do instead is create a constructor that initializes the members for you. This way, when you sublass this struct later on down the line, you just use this constructor to aid you in constructing the subclasses. This is free, safe code! use it!

Edit: The caveat to this is that if you have a huge code base already, don't change it until you start subclassing the structs. It works as it is now.

San Jacinto
+6  A: 

Yes, but only if foo is a POD. If it's got virtual functions or anything else remotely C++ish, don't use memset on it since it'll stomp all over the internals of the struct/class.

What you probably want to do instead of memset is give foo a constructor to explicitly initialise its members.

If you want to use new, don't forget the corresponding delete. Even better would be to use shared_ptr :)

Ben Hymers
Thanks Ben. After looking at some other files they have, I noticed they are using the new->delete way of initializing more so than creating a constructor for the struct. I am going to go with that since they do not have virtual functions. Thanks for the help.
garry
@garry: when using `new`, the constructor is still called. You could initialize its attributes there.
Bastien Léonard
Minor pedantry that in both C and C++, even with POD types it's technically undefined behaviour to just go around using `memset` to zero memory, and then read that memory back as anything other than `char` types and guaranteed-no-padding-bits `(u)intN_t` types. In practice, your implementation will arrange for all-0-bytes to mean a null pointer, a 0.0 float (as in IEEE754), and so on, but historically not all implementations always have done this.
Steve Jessop
+2  A: 

You could new foo (as is the standard way in C++) and implement a constructor which initialises foo rather than using memset.

E.g.

struct Something
{
    Something()
        : m_nInt( 5 )
    {

    }

    int m_nInt;
};

Also don't forget if you use new to call delete when you are finished with the object otherwise you will end up with memory leaks.

Konrad