2

Say, if I want to create a vector type of only for holding POD structures and regular data types. Can I do the following? It looks very unsafe but it works. If it is, what sort of issues might arise?

template <size_t N>
struct Bytes {
    char data[N];
};


std::vector<Bytes<sizeof(double)> > d_byte_vector;

std::vector<double>* d_vectorP = reinterpret_cast<std::vector<double>*>(&d_byte_vector);

for (int i=0;i<50;i++) {
 d_vectorP->push_back(rand()/RAND_MAX);
}

std::cout << d_vectorP->size() << ":" << d_byte_vector.size() << std::endl;
1
  • 2
    reinterpret_cast is usually a sign that you're doing something that better design could accommodate. And you want to only deal with POD, but reinterpret_casting this structure, I could conveniently start storing whatever I want in it. Commented Jan 27, 2014 at 20:54

2 Answers 2

4

No, this is not safe. Specific compilers may make some guarantee that is particular to that dialect of C++, but according to the Standard you evoke Undefined Behavior by instantiating an array of char and pretending it's actually something else completely unrelated.

Usually when I see code like this, the author was going for one of three things and missed one of the Right Ways to go about it:

  1. Maybe the author wanted an abstract data structure. A better way to go about that is to use an abstract base class, and move the implementation elsewhere.
  2. Maybe the author wanted an opaque data structure. In that case I would employ some variant of the pimpl idiom, where the void* (or char*) presented to the user actually points to some real data type.
  3. Maybe the author wanted some kind of memory pool. The best way to accomplish that is to allocate a large buffer of char, and then use placement-new to construct real objects within it.
Sign up to request clarification or add additional context in comments.

6 Comments

Memory Pool is probably the closest to what I was going for. But, writing STL allocators dealing with memory pools is not very easy.
@rwb: Standard Library allocators and memory pools using placement-new are not directly related concepts. I'm not sure why you're concerned about this?
I can use placement new to create an array from an existing memory buffer. But it wouldn't give me vector like capabilities. Moreover, this type of casting allows me to abstract the vector.
@rwb: What vector like capabilities are you lamenting the loss of? Keep in mind you can use pointers to contigious storage as if they were iterators -- because they basically are.
With vector, it expands its memory automatically, where as with an array I have to do it manually. But, I misspoke, the problem here is related to the abstract data structure, not memory.
|
1

No, this is not safe and generally not recommended because compilers aren't required to operate in a method that allows it. With that said, I've found exactly one reason to ever do this (very recently as well) and that is a variant of the pimpl idiom where I wanted to avoid pointers so that all of my data access could avoid the need to allocate memory for, deallocate memory for, and dereference the extra pointer. That code isn't in production yet and I'm still keeping an eye on that section of code to make sure that it doesn't start causing any other problems.

Unless you're generating code that has to be Extremely optimized, I would recommend finding some other way of doing whatever it is you need to do.

6 Comments

That's somewhat similar to what I'm trying to do, but couldn't figure out a clean way using the PIMPL idiom.
Were you just unhappy with the performance of the pimpl idiom or was there some problem that was keeping it from working?
Good question, I was trying to have an abstract interface where I can create a vector of any element type (provided they're POD) and push elements to it.
@rwb: That honestly sounds like more of a case of my #1 than a memory pool.
From my limited understanding of what you're trying to do, it sounds like you might just want to use a void* pointer that points to a vector. The header file won't need to contain any type information for the POD datatypes and in the class you just assign the pointer a new vector and use it that way. Still a little unsafe, but it's not an uncommon practice to use void* to hide the actual datatype of something.
|

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.