Is there a safe / standard way to manage unstructured memory in C ++?

I am creating a VM toy that requires a memory block to store and access data items of different types and sizes. I did this by writing a wrapper class around the uint8_t * data block of the required size. This class has some template methods for writing / reading typed data elements to / from arbitrary locations in a memory block, both of which verify that certain boundaries are not violated. These methods use memmove in what I hope is more or less safe. Nevertheless, although I am ready to continue to work in this direction, I must believe that others with great experience have been here before and could share their wisdom. In particular:

1) Is there a class in one of the C ++ standards (past, present, future) that was defined to perform a function similar to that described above?

2) If not, is there (preferably like in beer) a library that does?

3) In addition to this, in addition to checking boundaries and the inevitable problem of writing one type to a memory cell and reading other than this location, are there other problems that I should be aware of?

EDIT

It simplifies (i.e., the destructor and some other related methods) of what I'm trying to do; but he captures its essence:

#include <stdint.h> #include <assert.h> #include <string.h> #include <iostream> class block { private: uint8_t *data; size_t size; protected: block(const void* src, size_t size) : data(new uint8_t[size]), size(size) { ::memmove(data, src, size); } void set(const void* src, size_t dst_adr, size_t len) { assert( (size > dst_adr) && (size > len) && ( (size - len) > dst_adr) ); ::memmove(data+dst_adr, src, len); } void* get(size_t src_adr) const { assert( size > src_adr ); return data+src_adr; } public: block(size_t size) : data(new uint8_t[size]), size(size) {} size_t get_size() const { return this->size; } virtual void copy(const block& src, size_t src_adr, size_t dst_adr, size_t len) { // Bounds check assert( (size > dst_adr) && (size >= len) && ( (size - len) >= dst_adr) ); assert( (src.size > src_adr) && (src.size >= len) && ( (src.size - len) >= src_adr) ); ::memmove(data+dst_adr, src.data+src_adr, len); } }; template <typename T> class typed_block : public block { public: typed_block(const T& val) : block(&val, sizeof(T)) {} // Could use reinterpret_cast here instead, per Ben Voigt below operator T () const { return *((T*) this->get(0)); } typed_block<T>& operator=(const T& val) { this->set(*val, 0, get_size()); return *this; } }; int main(int argc, char** argv) { block db(512); typed_block<long> x(1 << 30); typed_block<short> y(0); db.copy(x, 0, 15, x.get_size()); y.copy(db, 17, 0, y.get_size()); std::cout << "x = " << x << "\ty = " << y << std::endl; return 0; } 

So, I assume that I really get if there are class libraries available (as in or from any C ++ standards) that provide essentially this functionality. I assume that it’s inconvenient for me to pass "void *" parameters (even as protected members) in the block class, and I'm looking for a safer way to do this in general.

thanks

- &. & Amp;
+4
source share
3 answers

Hmm, since you're in C ++, it looks like you're looking for STL allocator and / or new placement .

+5
source

There is reinterpret_cast , but this requires proper alignment, memmove not.

+1
source

If you select the boost :: variant array, you can allow several different types at each position; however, the amount of space allocated to the element will be equal to the maximum for all possible types. Please note that if you use only primitive types and void *, then this does not waste so much space.

+1
source

Source: https://habr.com/ru/post/1306757/


All Articles