共享内存不能使用指针《转载》

    技术2022-06-10  61

    好象是腾讯面试的第一个问题,当时就懵了,从来没有想过这个问题,然后也没有怎么考虑就说应该可以吧。回来一想便知道这是不可以的。A进程创建共享内存,如果共享的数据里面包含了指针那么指针指向的地址是A进程地址空间的某个逻辑地址,在B进程访问该地址肯定要出错的。下面的示例代码演示了这个错误。      A进程执行下面的代码,它往共享内存里面放的是一个结构体,其中有一个指针指向一个常量字符串。该程序运行会输出共享内存映射到它地址空间的位置。 #include <stdlib.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <string.h> char* str = "fuzhijie"; //要存储的数据 typedef struct{         char* name;         int age; } people; int main(int argc, char** argv) {         int shm_id, i;         key_t key;         char temp;         people *p_map;         char* file = "/home/ecy/lili";         key = ftok(file, 0);                  if(key==-1)         {                 perror("ftok error");                 return -1;         }         /*先用ftok创建一个key,再调用shmget,创建一块共享内存区域*/         shm_id = shmget(key, 4096, IPC_CREAT | 0660);         if(shm_id==-1)         {                 perror("shmget error");                 return -1;         }         /*将这块共享内存区附加到自己的内存段*/         p_map = (people*)shmat(shm_id, NULL, 0);         if (p_map == (void *)-1)         {             perror("shmat error");             return -1;         }         people p;          p.name = str;         p.age = 20;         memcpy(p_map, &p, sizeof(people));         printf("%p, %p/n", p_map, p_map->name);         return 0; } 程序输出如下: 0xb7781000, 0x80487b0       B进程从A进程创建的共享内存中读取数据,其同样也打印出共享内存映射到它的地址空间的位置。 #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include <unistd.h> #include <stdio.h> typedef struct{         char* name;         int age; } people; int main(int argc, char** argv) {         int shm_id,i;         key_t key;         people *p_map;         char* name = "/home/ecy/lili";         key = ftok(name,0);         if(key == -1)         {             perror("ftok error");             return -1;         }         shm_id = shmget(key, 4096, IPC_CREAT);         if(shm_id == -1)         {             perror("shmget error");             return -1;         }         p_map = (people*)shmat(shm_id,NULL,0);         printf("%p, %p/n", p_map, p_map->name);         printf("name = %s, age = %d/n", p_map->name, p_map->age);         if(shmdt(p_map) == -1)         {             perror(" detach error ");             return -1;         }         return 0; } 程序输出如下: 0xb78d6000, 0x80487b0 name = /home/ecy/lili, age = 20       可见共享内存在A,B进程映射的位置并不一样,在A进程中0x80487b0地址存放的是"fuzhijie"这个字符串的其实处,在B进程却不是,所以这将导致错误。A进程一部分内存情况如下:        B进程0x80487b0地址存放的内容却如下:        虽然没有访问到非法内存,但是数据是不对的,所以共享内存不能使用指针。我在网上偶然看到一句话说ACE里面的共享内存可以使用指针,有时间需要去考究一下。


    最新回复(0)