0

This is a follow-up question from question, where I have a struct like

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

How would I initialize all members if the object is malloc() by someone else and passed it to me for quick processing (in a function myFunc that I am in charge of). How do I make sure in function myFunc that numerical members are initialized to be 0, string members are initialized to be empty string?

strMyStruct *p = (strMyStruct *)malloc(sizeof(x1));
myFunc(p);

UPDATE 1

Since the members of the struct may change frequently, I don't want my code to refer to any individual members.

Community
  • 1
  • 1
packetie
  • 4,839
  • 8
  • 37
  • 72
  • 1
    Don't! We just told you in the other thread not to use `malloc` like this, it's not safe! If you initialize as `strMyStruct x1{}` as we said in the other question, it will do exactly what you are describing – Cory Kramer May 22 '15 at 19:31
  • @CoryKramer, this sounds crazy, but I am the poor guy got passed the block of memory that's large enough the struct and made sure all members are initialized before doing something else :-( . – packetie May 22 '15 at 19:37
  • I don't understand why you're trying to do this. If you instantiate the variable as I mentioned, **the values will have exactly what you are asking for** – Cory Kramer May 22 '15 at 19:38
  • Run [this code](http://cpp.sh/4byi), all the members are initialized! – Cory Kramer May 22 '15 at 19:40
  • @CoryKramer, in previous question, your answer solves my problem when I declare a local object. Here, I am just passed a block of memory that's of size of the struct, how do I invoke the constructor? placement new? – packetie May 22 '15 at 19:41
  • Yes, your code works (that's why I accepted your answer in previous question :-) ). However, in this question, the situation is slightly different, I don't get to declare a local object. I am going to accept the placement solution by @Bill Lynch. – packetie May 22 '15 at 19:47

2 Answers2

2

As recommended by @BillLynch, you need to use placement new. You can make his suggestion safer by using something along the lines of

std::unique_ptr<strMyStruct, placement_deleter> uptr = new(p) strMyStruct;

where placement_deleter is

struct placement_deleter {
   void operator()(strMyStruct *pointer) const {pointer->~strMyStruct()};
}

See if this works...

  • It doesn't apply to my situation where I need to do something on the fields from the memory block passed on to me, but I like it, so I up-voted it :-) – packetie May 22 '15 at 19:52
  • Oh - you need to return an initialized object? Ouch. –  May 22 '15 at 19:57
0

This is a terrible idea. You really should be allocating this object with new instead of malloc().

But if we have to, we can use placement new to allocate a C++ object in a preallocated piece of memory:

strMyStruct *p = (strMyStruct *) malloc(sizeof(*p));
new(p) strMyStruct;

And make sure you call the destructor before you call free():

p->~strMyStruct();
free(p);
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
  • This is a horrific idea. `unique_ptr` at least... – Puppy May 22 '15 at 19:34
  • @Puppy: I have no idea how `unique_ptr` solves this problem. Could you elaborate? – Bill Lynch May 22 '15 at 19:34
  • Step one: make_unique factory takes care of all this crap for you. Step two: destructor guarantees correct cleanup. Step three: move-only guarantees safety, e.g. exceptions. Simply allocating the object with `new` is a trivially tiny part of the problem. – Puppy May 22 '15 at 19:36
  • Thanks @Bill Lynch, your solution works! Will accept it in a few minutes when SO allows it. – packetie May 22 '15 at 19:43