memory mapping

Can someone point me in the right direction.
I want to open a file of a very specific size.
from there I want to assign pointers to various bytes in memory
I believe the best method of organizing them would be to create a data structure of pointers. The problem is I'm not very good with opening files. Most of my minimal experience reading from a file is through getline(). is there a way I can parse a file and directly access memory addresses of that file.
for instance, if I knew bytes 10 through 13 was a 32 bit number, it would be nice if I could cast a long pointer to 0x0A.

Is there a way of doing this?
So you want to read a file into memory and assign pointers to addresses in memory?
Last edited on
I'm not very good with opening files.

Check the tutorial for help.
http://www.cplusplus.com/reference/fstream/ifstream/open/

I could cast a long pointer to 0x0A.

You can't cast a long pointer to an absolute offset, but you can create a pointer to the base address of the buffer + 10 bytes.

1
2
3
4
5
6
7
8
9
10
11
 
  size_t eof; 
  // Open the file in binary (not text) mode. 
  ifstream datafile ("filename", ios::binary);
  //  position to eof 
  //  get the current position (eof)
  //  Reposition to the start of the file   
  char * buf = new char[eof];  // Allocate a buffer for the file 
  datafile.read (buf, eof);  // Read the file into the buffer
  long * ptr = (long *)(buf + 10);  // Point to a long starting at the 10th byte of the buffer
  cout << "long at offset 10 = " << *ptr << endl;


edit: I should note that doing this may not be portable across platforms due to endiness issues.
http://en.wikipedia.org/wiki/Bigendian

Also, note that the size of a long is implementation dependent, so a long might be 32 bits or 64 bits depending on your compiler. I would stronly suggest wrapping access in a function:
1
2
3
4
//  Return a pointer to an int 32
int32_t * get_int32ptr (char * buf, long offset)
{  return (int32_t *)(buf + offset);
}

Last edited on
I think you want File Mapping. This is pretty straight forward to do on Windows: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366556(v=vs.85).aspx

On *nix I don't even know if it's necessary. What platform are you using OP?
AbstractionAnon,

Thanks for you help. That sounds like exactly what I wanted to do. I don't quite understand the last part but I am aware of longs being inturpreted as both 32 and 64 bit. If what you proposed at the bottom can remedy this, I'll look into it.

As for endianness issues, I generally don't deal with big endian architectures. When it comes to that I'll figure it out.
Regarding the second snippet:
int32_t is a type that is guaranteed to be 32 bits.
You need to include the <cstdint> header.
http://www.cplusplus.com/reference/cstdint/

The function returns a pointer to a 32 bit value in your buffer. The function accepts the address of the buffer holding the file and the desired offset into the buffer (e.g. 10). It then performs the needed address arithmetic and returns you a pointer to the data you wanted. Using the function tends to be a lot clearer that doing the address arithmetic every time.

You would call it as follows:
1
2
3
4
 
  int32_t * pdata;  // pointer to some 32 bit data item in the file
  pdata = get_int32ptr (buf, 10);  // where buf is the memory buffer for the file 
  cout << "32 bit value = " << *pdata << endl;


Registered users can post here. Sign in or register to post.