[英]How do you get a std::list to allocate memory for n amount of objects in C++?
[英]In C++, How std::list in a struct will allocate memory and while using this in file mapping, the list result as empty
面臨的問題:使用文件映射共享的列表不會在列表中提供任何數據...
我有一個進程1,其中我將我的所有數據存儲為hash_map的列表,然后我嘗試在Process2中使用文件映射共享...當我嘗試檢索列表中的數據時,列表中沒有找到數據..
PS:我的exe與dll捆綁在一起,我把我的dll作為process1和exe作為process2 ...
這是我的代碼,
處理1
/* this is in common headerFile */
typedef hash_map <std::wstring,std::wstring> AttrValues;
CString FileName = L"E:\\DataLog.txt";
TCHAR szName [] = TEXT(“Local \\ MyFileMappingObject”);
struct ADstruct
{
std::list<AttrValues> StList;
int i;
};
/*Sharememory.cpp*/
DWORD SharedMemory()
{
AttrValues HardCode;//Sample data which i am hard coding for testing
HardCode[L"NAme"] = L"Test";
HardCode[L"D.Name"] = L"SAP";
std::list <AttrValues> HardCodedList;
HardCodedList.push_back(HardCode);
ADstruct CheckStruct;
CheckStruct.i = 10;
CheckStruct.StList = HardCodedList;
HANDLE hFile = INVALID_HANDLE_VALUE;// HANDLE hFile;
hFile = CreateFile(FileName.GetBuffer(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
printf("Error in creating a file..!");
return 0;
}
hMapFile = CreateFileMapping(
hFile, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order DWORD)
sizeof(ADstruct), // maximum object size (low-order DWORD)
szName); // name of mapping object
if (hMapFile == NULL)
{
_tprintf(TEXT("Could not create file mapping object (%d).\n"),
GetLastError());
return 1;
}
ADstruct *ADobj = new ADstruct;
ADobj = (ADstruct *) MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
sizeof(ADstruct) );
CopyMemory( (ADstruct *) ADobj, &CheckStruct , sizeof(ADstruct) );
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
return 0
}
過程2:
BOOL ReadMemoryMapping()
{
hash_map<LPWSTR,LPWSTR> ADdata;
HANDLE hMapFile;
HANDLE hFile = INVALID_HANDLE_VALUE;
hMapFile = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
szName); // name of mapping object
if (hMapFile == NULL)
{
_tprintf(TEXT("Could not open file mapping object (%d).\n"),
GetLastError());
return 1;
}
ADstruct * readstruct;
readstruct = (ADstruct *) MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
sizeof(ADstruct));
_tprintf(L"\nprint data%d\n",readstruct->i);
AttrValues At ;
for(std::list<AttrValues>::iterator list_iter = readstruct->StList.begin();
list_iter != readstruct->StList.end(); list_iter++)
{
At.clear();
At = *list_iter; //*****Here the code crashes as there is no datas inside***
if(At.empty() == 1)
printf("List is empty\n");
std::wcout<<endl<<endl<<"Attribute List In EXE : StList"<<endl;
for(AttrValues :: iterator it1 = list_iter->begin(); it1!= list_iter->end(); it1++)
{
std::wcout<<it1->first<<endl;
std::wcout<<it1->second<<endl;
}
}
UnmapViewOfFile(readstruct);
CloseHandle(hMapFile);
return 0;
}
首先,常規std::list
是一個多級數據結構,它包含對地址空間中其他位置的引用。 實際的列表元素不存儲在std::list
對象中。 它們存儲在內存中的其他位置。 而std::list
只是通過指針引用這些元素。 您的文件映射只是共享頂級std::list
對象,但它甚至不會嘗試共享實際的列表元素。
其次,即使你以某種方式設法神奇地確定和共享整個地址空間區域,其中包含與你的std::list
相關的每一個,它仍然無法工作,除非你以某種方式確保在所有進程中內存映射到完全相同地址空間中的區域。 這適用於使用指針的任何數據結構。
換句話說,它無法完成。 您不能只使用現有的普通std::list
並通過內存映射進行共享。
實際上,您嘗試使用CopyMemory
等函數復制非平凡對象(如std::list
)可能已足以破壞對象的完整性。 無需涉及內存映射。
你有可能改變。 標准庫模板是:
template<class T, class Allocator = std::allocator<T> > class list;
因此,如果需要,您可以提供自己的內存分配器作為第二個模板參數。 如果你使用默認的,它基本上是new
,它將從堆中分配節點,這不會在共享內存中。 (這似乎就是你如何使用內存映射文件。)另一個進程將能夠讀取每個列表的頭部,而不是其他任何地方分配的其余節點。
但是,您可以在共享內存中分配一個節點池,並編寫自己的分配器,分配該共享內存的塊,直到它消失為止。 (如果每個共享內存塊都可以重用,共享內存可以是它自己的迷你堆。如果你可以在完成它們的同時刪除所有列表,那么,取消映射就足夠了共享內存塊。)
或者你可以編寫自己的列表類,使用索引到共享內存中的節點池,而不是指針,這是一個實際上可以存儲在文件中的布局。 或者您可以在共享內存中靜態分配std::array
。 它的所有存儲都在類對象本身內部,並且它是固定大小的,因此它不會在共享塊之外分配任何內存,並且可以開箱即用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.