How to send vector<vector<type>> via MapViewOfFile

白昼怎懂夜的黑 提交于 2019-12-25 08:58:00

问题


I have the following code in a parent process:

vector<vector<double> > matrix(n); /* matrix NxM */
/* pushing data */
HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE,
    0, PAGE_READWRITE, 0, 2*sizeof(int) + sizeof(double)*n*m, lpName);

LPVOID lp = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);

mat_tmp* tmp = (mat_tmp*)lp;
tmp->n = n; tmp->m = m;
tmp->vv = vector<vector<double> >(matrix.begin(), matrix.end());

In a child process I'm trying to receive this vector >, but my child process terminate every time.

LPTSTR lpName = _tcsdup(TEXT(map_name));
HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE,
    0, PAGE_READWRITE, 0, 2*sizeof(int) + sizeof(double)*n*m, lpName);
LPVOID lp = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);

mat_tmp * tmp = (mat_tmp*)lp;
vector<vector<double> > matrix(tmp->vv.begin(), tmp->vv.end());

Error occurs when I'm trying to use data from matrix in child process. And the little struct is following:

struct mat_tmp
{
    int n; int m; vector<vector<double> > vv;
};

How can I receive my vector correctly in a child?


回答1:


Its not going to work the way you are doing it at the moment. The mapped memory will contain n & m and the internal structure of the vector class which will probably be a couple of pointers, depending on your STL implementation. Followed by a load of junk. You'll not be able to safely access these pointers from the other process as it is in a different address space.

You need to actually copy the memory pointed to by the vector into the mapped memory and reconstruct the vector on the other side.

Additionally the size of the memory you need is not going to be sizeof(int)*n*m. It looks like you want to have 2 ints n & m in the structure and an collection of n*m doubles.

So, allocate 2*sizeof(int) + n*m*sizeof(double). Copy n & m into the memory and then copy the rows of the matrix in. On the receiving side, read n & m and then deserialize the data into your vector of vectors.

Maybe make the struct like this:

struct mat_tmp
{
    int n; int m; double vv[1];
};

Then, copy directly into the shared memory:

double* dst = tmp.vv;
for (size_t y = 0; y < matrix.size(); ++y) {
   memcpy(dst, &(matrix[y][0]), matrix[y].size()*sizeof(double));
   dst += matrix[y].size();
}

On the other side,

dst_matrix.resize(n);
for (size_t y = 0; y < n; ++y) {
    dst_matrix[y].resize(m);
    memcpy(&(dst_matrix[y][0]), tmp + (y * m), m * sizeof(double));
}

All untested and could be made more optimal but hopefully it explains better what you need to do.




回答2:


You need to override the default allocator object for the vector to so that it works entirely in the memory space of the MapView, since the default allocator object will use heap memory for all allocations. There is a very old Dr.Dobbs article that Bjarne Stroustrup (creator of C++) wrote that tells exactly how to accomplish this task:

http://www.drdobbs.com/creating-stl-containers-in-shared-memory/184401639




回答3:


This won't work, the vector will only hold a pointer, the actual data is heap-allocated. Your memcpy only copies the pointer, which is invalid on the side of the recipient.



来源:https://stackoverflow.com/questions/13972712/how-to-send-vectorvectortype-via-mapviewoffile

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!