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

本文通过实例演示了在两个进程间使用共享内存时为何不能包含指针。文章详细解释了A进程创建的共享内存中若包含指向特定地址的指针,则在B进程访问时将因地址映射不同而出现问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

好象是腾讯面试的第一个问题,当时就懵了,从来没有想过这个问题,然后也没有怎么考虑就说应该可以吧。回来一想便知道这是不可以的。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、付费专栏及课程。

余额充值