javaLover javaLover - 24 days ago 7
C++ Question

How to use void* as a single variable holder? (Ex. void* raw=SomeClass() )

I am trying to make

void*
to hold a value (to avoid default constructor calling).

I want to:-


  • copy K to void* e.g.
    K k1; --> void* raw=k1;

  • copy void* to K e.g.
    void* raw; --> K k2=raw;

  • try not to break destructor and causes memory leak

  • don't use any dynamic allocation (heap, performance reason)



Here is what I tried:-

class K{
public: std::string yes="yes" ;
};

int main() {
//objective: k1->raw->k2 , then delete "raw"
void* raw[sizeof(K)]; //<--- try to avoid heap allocation
K k1;
static_cast<K>( raw)=k1; //<--- compile fail
K k2= static_cast<K>( raw);
std::cout<<k2.yes; //test
static_cast<K&>(raw)::~K(); //mimic destructor
return 0;
}


Question: Please provide a valid code that demonstrate a correct way to do this.

I found how to use placement new (http://stackoverflow.com/a/4756306/3577745 ), but not found how to use
void*
for a variable that is not an array.

C++ is new for me.

Edit :

I am writing a very custom collection (array).

Each element is encapsulated in a custom structure
KCap kcap
(with hold only 1 element, i.e.
K
).

Thus, I have to declare
K k
as a field of the encapsulator
KCap
.

However, I want to avoid default constructor of
K
, so I think
void*
can solve my issue.

Answer

What you are trying to do doesn't make sense. A void * is used to hold an arbitrary type of pointer, not an arbitrary type of other object. If you want to use storage for an arbitrary object type, use a char[].

Other problems with your code include that you need to ensure correct alignment of the raw storage, use reinterpret_cast to a reference rather than static_cast to a non-reference, your in-place destructor call syntax is wrong, and that you don't construct the K object in the "raw" storage. Here's a corrected version:

#include <string>
#include <iostream>

class K{
    public: std::string yes="yes"   ;
};

int main() {
    //objective:  k1->raw->k2  , then delete "raw"
    alignas(alignof(K)) char raw[sizeof(K)];        //<--- try to avoid heap allocation
    K k1;
    new (reinterpret_cast<K *>(&raw)) K(k1);     //<--- compile now succeeds :)
    K k2= reinterpret_cast<K &>(raw);
    std::cout << k2.yes << std::endl;           //test
    reinterpret_cast<K&>(raw).K::~K();  // call destructor
    return 0;
}