向同名共享内存写入的数据大小不一样问题

来源:互联网 发布:软件合成系统 编辑:程序博客网 时间:2024/06/11 19:50

以同样的名字申请不同大小的共享内存中出现的问题

1、当我们使用CreateFileMapping时,我们告诉系统文件映射对象需要多大的物理存储器,此时会返回一个句柄给调用线程,这个句柄用来标识所创建的文件映射对象,

2、第二步我们需要使用MapViewOfFile.用来为文件的数据预订一块地址空间区域并将文件的数据作为物理存储器调拨给区域。将文件的数据映射到进程的地址空间

分析:首先我们一般会先创建一个共享内存的内核对象。Write之后然后用Read从共享中读取数据,在读取的时候我们会释放对象,也就是这个句柄,但是很不好意思,实际上,这个操作并不是我们想的这么美好,我们在open的时候会再返回一个句柄,尽管指的都是同一块内存,但是句柄的值是不一样的。当我们在read中读取之后并释放这个句柄的时候,只是我们open回来的句柄被我们关闭了,(当然我们会将句柄置为null)。所以其实在读取并关闭之后Create中创建的句柄还在。

于是我们想是不是可以在Write的函数中在打开的时候查看是不是存在,若是存在则关闭句柄。但是在open之后还会返回一个新的句柄值,尽管它们都指向的是同一块内存。

上面述说的事情,或许在每次都读取一样大小的数据是没有问题的,但是一旦我们向共享内存中写入的数据大小不一样的时候,应该说是更大的数据时候。通常我们创建之前会判断是否存在,然后关闭,再创建,可惜,这个再次创建的还是之前的,因为在内核对象中,若是对象的名字是一样的是不会再次创建的,而只是调用而已。于是这个内存的数据大小还是最初创建的1024个字节。现在我们要写入3000的数据,于是在memcpy中就会访问非法的地址。

这个问题整整困扰了我两天,我分析程序中每一个使用共享内存的地方,担心没有设置互斥。但是都正确,最后迫不得已使用了一个ProcessExplore的软件查看发现还有没有关闭的,现在问题发现了,那就好办了,直接的查找同名的,切记在读取数据中操作是达不到效果的,因为写与读会发生在两个不同的进程中,所以在写入数据的前面进行这一项的操作。


int WriteDataToMap(char *strMapName,int size,char *&buf){DWORD dwMapsize=18+size;for(int i=0;i<g_Maps&&i<200;i++){if(strcmp(strMapName,g_StrMap[i].nm)==0){CloseHandle(g_StrMap[i].hdl);memset(g_StrMap[i].nm,0,100);g_StrMap[i].hdl=NULL;g_Maps--;}}HANDLE hDbMap=OpenFileMapping(FILE_MAP_READ, FALSE, strMapName);if (GetLastError() == ERROR_ALREADY_EXISTS) {printf("文件%s已经存在.\n",strMapName);CloseHandle(hDbMap);hDbMap=NULL;}hDbMap=CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE , 0, dwMapsize, strMapName);if(hDbMap!=NULL) {if (GetLastError() == ERROR_ALREADY_EXISTS) {printf("文件%s已经存在.\n",strMapName);CloseHandle(hDbMap);hDbMap=NULL;return -2;}else{LPBYTE lpData = (LPBYTE)MapViewOfFile(hDbMap,  FILE_MAP_WRITE, 0, 0, 0);if (lpData == NULL)//映射未成功{printf("文件映射失败");CloseHandle(hDbMap);hDbMap=NULL;return -1;}g_Maps++;memcpy(g_StrMap[g_Maps-1].nm,strMapName,100);g_StrMap[g_Maps-1].hdl=hDbMap;memset(lpData,0,dwMapsize);memcpy(lpData,&hDbMap,sizeof(HANDLE));memcpy(lpData+sizeof(HANDLE),&size,sizeof(int));memcpy(lpData+sizeof(int)+sizeof(HANDLE), buf,size );UnmapViewOfFile(lpData);}}return 1;}int ReadDataFromMap(char *pMapName,char  *&lpbReceive){LPBYTE  lpbReceiveBuf;int size=0;HANDLE hReceiveMap = OpenFileMappingA(FILE_MAP_READ, FALSE, pMapName);   if (hReceiveMap!=NULL)   {   g_Maps++;   g_StrMap[g_Maps-1].hdl=hReceiveMap;   memcpy(g_StrMap[g_Maps-1].nm,pMapName,100);      lpbReceiveBuf = (LPBYTE)MapViewOfFile(hReceiveMap,FILE_MAP_READ,0,0,0);//将内存区域映射到进程地址空间中   if (lpbReceiveBuf == NULL)   {    CloseHandle(hReceiveMap);    hReceiveMap=NULL;//关闭内核对象,仅仅closeHandle是不够的,因为在进程句柄表中,这一项还是存在的,下次利用的时候               //不知道会是什么对象,它只是一个索引而已。tj理解    return -2;   }   HANDLE ldh;   int n=0;   memcpy(&ldh,lpbReceiveBuf+n,sizeof(HANDLE));//句柄   n+=sizeof(HANDLE);   memcpy(&size,lpbReceiveBuf+n,sizeof(int));//长度   lpbReceive=new char[sizeof(int)+size+sizeof(HANDLE)];//分别为地址,长度   if(lpbReceive!=0)   {    if(size>0)    memcpy(lpbReceive,lpbReceiveBuf+sizeof(HANDLE),sizeof(int)+size);//具体数据   }       UnmapViewOfFile(lpbReceiveBuf);   }return size;}


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 离婚判决不服上诉期限过了怎么办 法院判完执行厅不执行怎么办 民事判决书下来又有新的证据怎么办 民事判决书下来欠钱没钱法院怎么办 法院笔录没看清就签字了怎么办 有人模仿自己笔迹在法院签字怎么办 房屋未签合同中介定金不退怎么办 临时摊位买的东西想退怎么办 租房合同签了房东不想租了怎么办 租房合同签了不想租了怎么办 租房合同刚签一天不想租怎么办 买二手房房东不交物业费怎么办 买二手房原房主欠物业费怎么办 客人将物品遗留在餐厅时怎么办 工程签合同了又别人来干怎么办? 超市储存柜东西忘拿了怎么办 普通异性朋友出去玩在外面住怎么办 古墓丽影崛起绳箭突然没有了怎么办 pp材质的水杯用开水烫了怎么办 手上长水泡很痒怎么办有什么药膏 烧伤后水泡破了周围都肿了怎么办 烧伤的水泡破了碰到水怎么办 浓硫酸沾到皮肤上应该怎么办 将浓硫酸沾到皮肤上怎么办 刷厕所的盐酸弄到皮肤上怎么办 死刑犯被执行后发现被冤枉的怎么办 觉得老公对自己不够关心体贴怎么办 孕期老公不知道关心不体贴怎么办? 中国和伊朗做贸易美国制裁怎么办 土地被村民霸占村长解决不了怎么办 村支书霸占群众选举村长的票怎么办 苹果手机自带的音乐软件删了怎么办 不小心把手机系统软件删了怎么办 佳能打印机打相片是打不全怎么办 卖家说我寄回去的包是假的怎么办 辞职后原单位没把档案给转出怎么办 天下行以租代购要起诉我怎么办 顺丰收件人电话地址都写错了怎么办 领导问任务完不成怎么办怎么回答 我和我老婆感情出现问题了怎么办 手机坏了手机浏览器里照片怎么办