1

I have an array of doubles stored in a memory mapped file, and I want to read the last 3 entries of the array (or some arbitrary entry for that matter).

It is possible to copy the entire array stored in the MMF to an auxiliary array:

void ReadDataArrayToMMF(double* dataArray, int arrayLength, LPCTSTR* pBufPTR)
{
    CopyMemory(dataArray, (PVOID)*pBufPTR, sizeof(double)*arrayLength);
}

and use the needed entries, but that would mean copying the entire array for just a few values actually needed.

I can shrink arrayLength to some number n in order to get the first n entries, but I'm having problems with copying a part of the array that doesn't start from the first entry. I tried playing with pBufPTR pointer but could only get runtime errors.

Any ideas on how to access/copy memory from the middle of the array without needing to copy the entire array?

Ron Teller
  • 1,880
  • 1
  • 12
  • 23
  • Are you calling MapViewOfFile on the relevant part? – Lorenzo Dematté Feb 17 '14 at 08:54
  • 1
    Also, it is not clear to me what CopyMemory does.. is the first parameter the source of the destination? Because in the former case, you should adjust dataArray offset, not pBufPTR. – Lorenzo Dematté Feb 17 '14 at 08:56
  • @LorenzoDematté its from the windows headers; consider it a `memcpy` equivalent. [See here for more info](http://stackoverflow.com/questions/8951775/win32-api-functions-vs-their-crt-counterparts-e-g-copymemory-vs-memcpy/8951915#8951915) – WhozCraig Feb 17 '14 at 09:00
  • @LorenzoDematté MapViewOfFile is called when I open the MMF, in a standard manner. – Ron Teller Feb 17 '14 at 09:22

2 Answers2

1

To find start offset for nth-element:

const double *offset = reinterpret_cast<const double*>( *pBufPTR ) + n;

To copy last 3 elements:

CopyMemory( dataArray, reinterpret_cast<const double*>( *pBufPTR ) + arrayLength - 3, 3 * sizeof(double) );
Ivan
  • 2,007
  • 11
  • 15
  • reinterpret_cast doesn't accept LPCTSTR* (`Error: reinterpret_cast cannot cast away const or other type qualifiers`) – Ron Teller Feb 17 '14 at 09:35
0

You can just add the (0 based) index of the first array element you want to copy to the dataArray pointer value that you pass in... the pointer will be increased by the index times sizeof(double). Makes sure you pass in an arrayLength value reflecting the number of elements to operate on, and not the original array length.

For example, to copy the last 10 elements (assuming you've already checked there are at least 10 elements)...

ReadDataArrayToMMF(dataArray + arrayLength - 10, 10, &myBufPTR);

Similarly (albeit illustrating a different notation to get the address), to get elements 20..24:

ReadDataArrayToMMF(&dataArray[20], 5, &myBufPTR);
Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • I believe this solution gives an offset to the destination array, but not to the source array in the MMF, meaning it will still copy the **first** `n` elements from the array in the MMF to the destination array (starting at some chosen index instead of 0). – Ron Teller Feb 17 '14 at 09:21
  • @RonTeller: possibly... I assumed `CopyMemory` ordered its arguments similarly to `memcpy`, which is a common practice for similar functions, but if you're saying the function does it the other way around then obviously you'd have to apply the same style of indexing to the last argument instead of the first. (Just maybe my intuition is actually right and that's why your program's been crashing...? ;-p) – Tony Delroy Feb 17 '14 at 09:28
  • problem is, regular pointer arithmetic doesn't work with LPCTSTR* – Ron Teller Feb 17 '14 at 09:32
  • @RonTeller You'll need to cast it to a `double*` first... e.g. `&((const double*)myBufPTR)[n]` or `static_cast(myByfPTR) + n` (you should also add a `const` to the parameter in the argument list for `ReadDataArrayToMMF` so it's obvious which one is the source vs. destination). – Tony Delroy Feb 17 '14 at 09:44