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

好象是腾讯面试的第一个问题,当时就懵了,从来没有想过这个问题,然后也没有怎么考虑就说应该可以吧。回来一想便知道这是不可以的。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里面的共享内存可以使用指针,有时间需要去考究一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值