text: This is a simple piece of code which dumps a section of memory - with address, hex values, and characters - to a stream. I've written something like this a lot of times over the years, whenever I've needed a quick memory dump to log during debugging.
  I wanted to make it easy to stream out, so I wrote this as a function which takes a memory address and number of bytes and returns an object with those parameters. This object's class has a function to dump the memory, and a befriended output operator that calls it, so the function can be called in a stream sequence.
  Since this is something I'd mostly use while debugging, I keep it all in a single header file, to make it easy to add when needed.
  #include <iostream>
  #include <iomanip>
  //! Class to send a memory dump to stream
  class mem_dumper
  {
  public:
  //! Constructor
  /*! Construct object that can be serialised out to stream
  \param address start address of memory to serialise
  \param length number of bytes to serialise
  */
  mem_dumper(const void* address, size_t length)
  : address_(address), length_(length)
  {}
  private:
  // Address of data to dump
  const void* address_;
  // Number of bytes to dump
  size_t length_;
  // Give streaming operator access to streaming function
  friend std::ostream& operator<<(std::ostream& os, const mem_dumper& md);
  // Streaming function
  std::ostream& dump(std::ostream& os) const
  {
  // Save stream state
  std::ios state(NULL);
  state.copyfmt(os);
  os << std::hex << std::setfill('0');
  size_t index = 0;
  const unsigned char* address = static_cast<const unsigned char*>(address_);
  while (index < length_)
  {
  // Address
  os << std::endl << std::setw(8) << (unsigned long)address_ + index;
  // Up to 16 bytes per line
  size_t width = (length_ - index) > 16 ? 16 : (length_ - index);
  // Hex codes
  for (size_t i = 0; i < 16; i++ )
  {
  // Gap after a 0 and 8 characters
  if( i % 8 == 0 )
  os << ' ';
  // Put in filler if we run out of bytes at the end
  if( i < width )
  os << ' ' << std::setw(2) << std::hex << (unsigned short)address[i+index];
  else
  os << " ";
  }
  os << ' ';
  // Printable characters
  for( size_t i = 0; i < width; i++)
  {
  if( i % 8 == 0 )
  os << ' ';
  if( address[i+index] < 32 )
  os << '.';
  else
  os << address[i+index];
  }
  index += 16;
  }
  // Restore state
  os.copyfmt(state);
  return os;
  }
  };
  //! Stream operator for a mem_dumper
  /*! Stream operator for a mem_dumper
  \param os output stream
  \param md mem_dumper object to serialise
  \return output stream
  */
  std::ostream& operator<<(std::ostream& os, const mem_dumper& md)
  {
  return md.dump(os);
  }
  //! Create a mem_dumper which can be serialised
  /*! Create a mem_dumper which can be serialised
  \param address start address of memory to serialise
  \param length number of bytes to serialise
  \return mem_dumper object
  */
  inline mem_dumper mem_dump(const void* address, size_t length)
  {
  return mem_dumper(address, length);
  }
  To use it, simply pass in the address of the data and how many bytes you want to dump into the function, and send it to an output stream:
  #include "mem_dump.hpp"
  struct ExampleData
  {
  char text[22];
  bool b;
  int i;
  ExampleData()
  {
  memcpy(text, "Blabla bla. Blah? Bla!", 22);
  b = true;
  i = 1234567;
  }
  } data;
  std::cout << mem_dump(&data, sizeof(ExampleData)) << std::endl;
  This will produce (address will vary, and the characters representing the int bytes will vary depending on platform codepage):
  int
  0022FAC8 42 6c 61 62 6c 61 20 62 6c 61 2e 20 42 6c 61 68 Blabla b la. Blah
  0022FAD8 3f 20 42 6c 61 21 01 cc 87 d6 12 00 ? Bla!.╠ çÍ.
  This article, along with any associated source code and files, is licensed under The BSD License
  std::ostream& operator<<(std::ostream& os)
  {
  return dump(os);
  }
  General News Suggestion Question Bug Answer Joke Praise Rant Admin
  Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.