`
mmdev
  • 浏览: 12929631 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

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

相关推荐

    C#操作共享内存读写工程

    C#操作共享内存读写工程、C#操作共享内存读写工程、C#操作共享内存读写工程

    linux 共享内存浅析

    要使用共享内存,应该有如下步骤: 1.开辟一块共享内存 shmget() 2.允许本进程使用共某块共享内存 shmat() 3.写入/读出 4.禁止本进程使用这块共享内存 shmdt() 5.删除这块共享内存 shmctl()或者命令行下ipcrm ftok...

    C++智能指针实现(不用再担心你的内存泄露)

    设有Debug版本的断言,确保智能空指针不被使用。 /* 智能指针类 不能用于数组,指针指向的数据必须是new出来的 不能创造该类的指针 不能将任意实体指针分别赋值给两个不同的智能指针(通过构造函数或者=) */

    C语言内存空间使用与指针理解

    C语言内存空间使用与指针理解C语言内存空间使用与指针理解v

    通过指针读写内存.e

    易语言通过指针读写内存 .版本 2 .子程序 _按钮_复制内存_被单击 .局部变量 地址, 整数型 .局部变量 缓冲区, 文本型 地址 = 写内存 () 缓冲区 = 取空白文本 (API_取文本长度 (地址) + 1) API_复制内存 (缓冲区...

    最强版VB程序间共享内存,进程通信-共享变量,支持结构

    程序间共享内存,用于数据交换,非常强大的示例,解决你进程间数据共享的问题 不错,解决了传输问题,可以共享N个字符串。整数等类型 改造一下,进程通讯就可以用了 我用它做串口数据共亭。。不错。。 挺好用的我...

    易语言内存指针模块

    易语言内存指针模块源码,内存指针模块,指针_取子程序地址,取当前参数个数,指针_取通用类型,指针_强制转换,指针_取变量指针,指针_取,指针_取变量数据地址,指针_到整数,指针_是否有效,数组_通用加入成员,数组_取数组...

    内存使用和指针及C++ STL介绍

    讲解C语言的指针使用和相关的易出错问题和内存的使用,C++ STL的七大模块的使用和介绍

    指针参数传递内存

    用图片的和代码的方式解释指针参数传递内存

    C++智能指针(含内存计数)

    C++智能指针(含内存计数) 完美解决内存泄漏问题。 使用智能指针就像使用指针自己一样方便

    指针和内存分配详解

    深入的探讨了,指针和内存问题,很好的帮你解决指针和内存的各种疑惑

    C++指针 数组 内存释放.docx

    C++指针 数组 内存释放 相关说明

    Linux /Unix 共享内存

    创建共享内存时,shmflg参数至少需要 IPC_CREAT | 权限标识,如果只有IPC_CREAT 则申请的地址都是k=0xffffffff,不能使用; 获取已创建的共享内存时,shmflg不要用IPC_CREAT(只能用创建共享内存时的权限标识,如...

    内存与指针实质与联系(free)

    指针与内存关系的实质剖析

    C# 2.0 内存管理和指针

    如果很好地理解了内存管理和C#提供的指针功能,也就能很好地集成C#代码和原来的代码,并能在非常注重性能的系统中高效地处理内存。 本章的主要内容如下: ● 运行库如何在堆栈和堆上分配空间 ● 垃圾收集的工作原理 ...

    Delphi利用进程实现消息传送及内存共享.rar

    Delphi利用进程实现消息传送及内存共享,自己做的一个共享内存组件;原来是一个单元引用,加入进程间的消息传递;做成了组件;如果存在公用的内存镜像文件,将数据填充到指针中;否则创建它,如果存在公用的内存镜像...

    通过指针读写内存3种方法源码

    E语言实现的内存读写功能,可以通过指针来读写,用3种方法实现

    C指针系列之跨函数内存申请

    简单的C语言中使用指针在子函数内部申请内存并返回给主函数使用的范例。

    C和C++使用Lu键树实现智能指针及检查内存泄露

    C和C++使用Lu键树实现智能指针及检查内存泄露

    C#中使用不安全代码(使用指针的代码)

    例如,在下列情况中使用允许采用指针的不安全上下文是正确的: 处理磁盘上的现有结构 涉及内部包含指针的结构的高级 COM 或平台调用方案 性能关键代码 不鼓励在其他情况下使用不安全上下文。具体地说,不应该使用不...

Global site tag (gtag.js) - Google Analytics