Safe way to allocate block of memory
I am trying to create a class which I can use to safely allocate a block of bytes. One purpose is to allow me to easily fill in a variable with N bytes from the block. For example the code below would attempt to fill a variable (e.g. boost::uint32_t val ). template <typename Value_Type> void read (Value_Type* value) { m_file_img->read (reinterpret_cast<char*>(value), sizeof(Value_Type)); } The second purpose is to create a block of bytes which I can write bytes to at particular offsets from the beginning. For example if I created a block of 50 bytes I may want to fill in bytes 5 through 8 with 4 bytes of data. My present method is create a block via 'new char[size]' and store this pointer in a class. This works for reading by when later in my program when I create a instance to write data to it I get a segfault. I was wondering if there was a boost method for creating an array of bytes? My code is below. I would greatly appreciate comments on how to utilize more of boost's functionality. Stephen ----------------------- #ifndef MEMORY_MAP_H_ #define MEMORY_MAP_H_ #include <boost/cstdint.hpp> #include <boost/scoped_ptr.hpp> #include <boost/shared_ptr.hpp> #include <boost/format.hpp> #include <iostream> #include <iomanip> #include "io/exceptions/IO_Exception.hpp" namespace libreverse { namespace data_types { class Memory_Map { public: typedef char data_type; typedef char const* const_iterator; typedef data_type* iterator; typedef boost::shared_ptr<Memory_Map> ptr; Memory_Map ( boost::uint32_t const& size ); Memory_Map ( boost::uint64_t const& size ); Memory_Map ( Memory_Map const& rhs ); virtual ~Memory_Map(); template <typename Offset_Type> void seek ( Offset_Type offset ) { if (offset > m_size) { std::cerr << "The offset given, " << offset << " is invalid. Its pointing to a " << std::endl << "memory location outside of space " << "allocated to" << std::endl << "this Memory Map. (" << m_size << ")" << std::endl; throw errors::IO_Exception ( errors::IO_Exception::OUT_OF_RANGE ); } m_present_pos = m_base_addr + offset; std::cout << boost::format ("Memory_Map::seek - new present pos = %1p") % *m_present_pos << std::endl; } void read ( iterator dest_addr_ptr, boost::uint32_t const& len); void copy ( const_iterator src_addr_ptr, boost::uint32_t const& len ); iterator begin(); const_iterator begin() const; const_iterator end() const; iterator get_Present_Position (void); const_iterator get_Present_Position (void) const; boost::uint32_t const& size (void) const; private: char* m_base_addr; boost::uint32_t m_size; // Size of memory iterator m_present_pos; iterator m_end_addr; }; #endif /* MEMORY_MAP_H_ */ ---------------- #include "Memory_Map.hpp" namespace libreverse { namespace data_types { Memory_Map::Memory_Map ( boost::uint32_t const& size ) : m_size ( size ) { m_base_addr = new char[size]; m_present_pos = m_base_addr; /* std::cout << boost::format ("Memory_Map::constructor - start present pos = %1%") % boost::io::group ( std::hex, m_present_pos ) << std::endl; */ m_end_addr = m_base_addr + size; } Memory_Map::Memory_Map ( boost::uint64_t const& size ) : m_size ( size ) { m_base_addr = new char[size]; m_present_pos = m_base_addr; m_end_addr = m_base_addr + size; } Memory_Map::Memory_Map ( Memory_Map const& rhs ) : m_base_addr (rhs.m_base_addr), m_size (rhs.m_size), m_present_pos ( rhs.m_present_pos ), m_end_addr ( rhs.m_end_addr ) { /* std::cout << "Memory_Map::copy_constructor - start present pos = " << m_present_pos << std::endl; */ #warning We do not deep copy the data here } Memory_Map::~Memory_Map () { delete[] m_base_addr; } void Memory_Map::read ( iterator dest_addr_ptr, boost::uint32_t const& length ) { if ( m_present_pos > m_end_addr ) { std::cerr << "The present position pointer is invalid. " << "Its pointing" << std::endl << "to a memory location out side of space " << "allocated to" << std::endl << "this Memory Map." << std::endl; throw errors::IO_Exception ( errors::IO_Exception::INVALID_INDEX ); } memcpy ( dest_addr_ptr, m_present_pos, length ); m_present_pos += length; } Memory_Map::iterator Memory_Map::begin() { return m_base_addr; } Memory_Map::const_iterator Memory_Map::begin() const { return m_base_addr; } Memory_Map::const_iterator Memory_Map::end() const { return m_end_addr; } Memory_Map::iterator Memory_Map::get_Present_Position (void) { return m_present_pos; } Memory_Map::const_iterator Memory_Map::get_Present_Position (void) const { return m_present_pos; } boost::uint32_t const& Memory_Map::size (void) const { return m_size; } void Memory_Map::copy ( const_iterator src_addr_ptr, boost::uint32_t const& length ) { // If m_present_pos + length > m_end_addr ERROR if ( m_present_pos + length > m_end_addr ) { std::cerr << "The present position pointer will be" << " invalid if we write from the present" << std::endl << "position with the given length. It will" << " cause an segfault. Recheck the value" << std::endl << "given for length (" << length << ") or check" << " the setting of the present position." << std::endl; throw errors::IO_Exception ( errors::IO_Exception::OUT_OF_RANGE ); } memcpy ( m_present_pos, src_addr_ptr, length ); m_present_pos += length; }
participants (1)
-
Stephen Torri