免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3064 | 回复: 1
打印 上一主题 下一主题

[C] 请问怎么用mmap来存储两个结构体数据 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-02-20 00:48 |只看该作者 |倒序浏览
mmap.c
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>

struct record
{
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int hash;
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int key;
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int value;
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int offest;
};

struct xmap
{
&nbsp;&nbsp;&nbsp;&nbsp;struct record *records;
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int records_count;
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int size_index;
};


struct xmap *alloc_user_def_t(int fd)
{
&nbsp;&nbsp;&nbsp;&nbsp;struct xmap   *p;
&nbsp;&nbsp;&nbsp;&nbsp;struct record *recs;

&nbsp;&nbsp;&nbsp;&nbsp;p = (struct xmap *)mmap(NULL, sizeof(struct xmap) + sizeof(struct record) * 20, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
&nbsp;&nbsp;&nbsp;&nbsp;if (p == NULL)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return NULL;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;p->records = calloc(20, sizeof(struct record));
&nbsp;&nbsp;&nbsp;&nbsp;recs       = p->records;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;recs[0].hash   = 9832;
&nbsp;&nbsp;&nbsp;&nbsp;recs[0].key    = 87643;
&nbsp;&nbsp;&nbsp;&nbsp;recs[0].value  = 980;
&nbsp;&nbsp;&nbsp;&nbsp;recs[0].offest = 987;

&nbsp;&nbsp;&nbsp;&nbsp;recs[1].hash   = 8982;
&nbsp;&nbsp;&nbsp;&nbsp;recs[1].key    = 907;
&nbsp;&nbsp;&nbsp;&nbsp;recs[1].value  = 243;
&nbsp;&nbsp;&nbsp;&nbsp;recs[1].offest = 124;


&nbsp;&nbsp;&nbsp;&nbsp;p->size_index    = 9897;
&nbsp;&nbsp;&nbsp;&nbsp;p->records_count = 67;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;return p;
}


int main()
{
&nbsp;&nbsp;&nbsp;&nbsp;int fd, i;
&nbsp;&nbsp;&nbsp;&nbsp;struct xmap *ptr;
&nbsp;&nbsp;&nbsp;&nbsp;struct record *recs;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;fd    = open("data.mmap", O_CREAT|O_RDWR, 0777);

&nbsp;&nbsp;&nbsp;&nbsp;lseek(fd, (sizeof(struct xmap) + sizeof(struct record) * 20) -1 , SEEK_SET);
&nbsp;&nbsp;&nbsp;&nbsp;write(fd,"",1);

&nbsp;&nbsp;&nbsp;&nbsp;ptr  = alloc_user_def_t(fd);
&nbsp;&nbsp;&nbsp;&nbsp;recs = ptr->records;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;printf("recs[0].hash = %d\r\n", recs[0].hash);
&nbsp;&nbsp;&nbsp;&nbsp;printf("recs[0].key  = %d\r\n", recs[0].key);
&nbsp;&nbsp;&nbsp;&nbsp;printf("recs[1].hash = %d\r\n", recs[1].hash);
&nbsp;&nbsp;&nbsp;&nbsp;printf("recs[1].key  = %d\r\n", recs[1].key);

&nbsp;&nbsp;&nbsp;&nbsp;printf("ptr->size_index = %d\r\n", ptr->size_index);

&nbsp;&nbsp;&nbsp;&nbsp;munmap(ptr, sizeof(struct xmap) + sizeof(struct record) * 20);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;free(recs);
&nbsp;&nbsp;&nbsp;&nbsp;close(fd);
&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}




mmap_read.c

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>

struct record
{
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int hash;
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int key;
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int value;
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int offest;
};

struct xmap
{
&nbsp;&nbsp;&nbsp;&nbsp;struct record *records;
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int records_count;
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int size_index;
};


int main()
{
&nbsp;&nbsp;&nbsp;&nbsp;int fd, i;
&nbsp;&nbsp;&nbsp;&nbsp;struct xmap *ptr;
&nbsp;&nbsp;&nbsp;&nbsp;struct record *recs;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;fd    = open("data.mmap", O_CREAT|O_RDWR, 0777);


&nbsp;&nbsp;&nbsp;&nbsp;ptr  = (struct xmap *)mmap(NULL, sizeof(struct xmap) + sizeof(struct record) * 20, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
&nbsp;&nbsp;&nbsp;&nbsp;recs = ptr->records;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;printf("recs[0].hash = %d\r\n", recs[0].hash);
&nbsp;&nbsp;&nbsp;&nbsp;printf("recs[0].key  = %d\r\n", recs[0].key);
&nbsp;&nbsp;&nbsp;&nbsp;printf("recs[1].hash = %d\r\n", recs[1].hash);
&nbsp;&nbsp;&nbsp;&nbsp;printf("recs[1].key  = %d\r\n", recs[1].key);

&nbsp;&nbsp;&nbsp;&nbsp;printf("ptr->size_index = %d\r\n", ptr->size_index);

&nbsp;&nbsp;&nbsp;&nbsp;munmap(ptr, sizeof(struct xmap) + sizeof(struct record) * 20);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;close(fd);
&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}




mmap_read.c

        recs = ptr->records;
       
        printf("recs[0].hash = %d\r\n", recs[0].hash);
        printf("recs[0].key  = %d\r\n", recs[0].key);
        printf("recs[1].hash = %d\r\n", recs[1].hash);
        printf("recs[1].key  = %d\r\n", recs[1].key);

执行到这里 就有错误


struct xmap 结构体的 struct record *records; 大小是动态的

请大家帮我看看 怎么做用mmap 来保存这些数据

论坛徽章:
0
2 [报告]
发表于 2008-02-20 13:11 |只看该作者
在 mmap.c 里面需要修改两个地方:

  1. p->records = calloc(20, sizeof(struct record));
复制代码

修改为
  1. p->records = (struct record*)(((char*)p) + sizeof( xmap) );
复制代码


calloc 分配的内存不是在 mmap 出来的范围内的。看代码的原意,应该是上面修改后的意思吧。
修改之后的代码也不能保证总是正确。根本解决方法是在 xmap 里面不要用指针,因为指针式不能跨进程。
所有要用到指针的地方,改为用相对于开始位置(p)的 offset 来表示。

删除
  1. free(recs);
复制代码


运行结果为:


  1. bash$ ./w
  2. recs[0].hash = 9832
  3. recs[0].key  = 87643
  4. recs[1].hash = 8982
  5. recs[1].key  = 907
  6. ptr->size_index = 9897

  7. bash$ ./r
  8. recs[0].hash = 9832
  9. recs[0].key  = 87643
  10. recs[1].hash = 8982
  11. recs[1].key  = 907
  12. ptr->size_index = 9897
复制代码

[ 本帖最后由 iunknown 于 2008-2-20 13:18 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP