Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C M将文件映射并索引到内存以进行读/写操作_C_Mmap - Fatal编程技术网

C M将文件映射并索引到内存以进行读/写操作

C M将文件映射并索引到内存以进行读/写操作,c,mmap,C,Mmap,我试图通过映射一个与RAM大小相对应的1MIB文件来模拟一个基本CPU。我想读/写这个文件。我的困惑是,我认为我可以只映射我的文件,然后索引到内存块中,就好像它是一个数组一样。我在网上看到了一些例子,它们也起到了同样的作用。例如,给定以下代码段: int16_t ramD; if ( (ramD = open("ramMap.txt", O_RDWR | O_CREAT, 1)) == -1) { errx(EX_OSERR, "RAM could not be initialized"

我试图通过映射一个与RAM大小相对应的1MIB文件来模拟一个基本CPU。我想读/写这个文件。我的困惑是,我认为我可以只映射我的文件,然后索引到内存块中,就好像它是一个数组一样。我在网上看到了一些例子,它们也起到了同样的作用。例如,给定以下代码段:

int16_t ramD;
if ( (ramD = open("ramMap.txt", O_RDWR | O_CREAT, 1)) == -1)
{
    errx(EX_OSERR, "RAM could not be initialized");
}
uint16_t* ram = mmap(0, ram_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, ramD, 0);
如何访问此MMAP文件中的特定位置以进行读写?我以为它会像ram[36]一样简单,它会让我访问mmap返回的指针的第36字节偏移量,但事实似乎并非如此。为了测试,我做了一个printf%p\n,void*&ram;查看mmap指向的地址,该地址为0x7fffffffde18,顺便说一下,它与指定的mmap参数0相差甚远。同时,printf%p\n,void*&ram[36]返回0x7ffff7ee1048

mmap不是在线性块中给我内存吗?我在这里遗漏了什么?

这个

printf("%p\n", (void *) &ram);
提供堆栈上局部变量ram的地址。你想要

printf("%p\n", (void *)ram);
获取您映射的ram的地址。此外,由于您将ram声明为uint16_t,ram[36]将是内存字节72和73的第36个16位字


1从0开始计算当然

您不能将数组或任何内容放在地址0处。mmap上的文档说明:如果addr为NULL,那么内核将选择创建映射的地址;。另一个问题是,您似乎打算通过指向uint16\t的指针读取字节,此处可能是2个字节。printf%p\n,void*&ram;这里您正在打印ram变量的地址,根据打印的地址判断,很可能是在堆栈上分配的。您可能需要printf%p\n,void*ram;。如果将基址存储在uint16_t*中,则ram[36]会寻址偏移量72和73处的字节,而不是字节36,因为其大小是所指向单元大小的倍数。如果它是一个int数组,那么必须写入数组_of int[offset*sizeofint]才能得到offset处的整数就很烦人了。C不会让你这么做;写入数组_of_int[offset]以获取整数。类似的评论也适用于uint16_t*。你是否有可能使用macOS?@JonathanLeffler没有,Windows使用的是基于云的ubuntu IDE。谢谢,这让我明白了很多。但仍然存在一个问题:我从printf%p\n,void*ram获取0x7ffff7ee1000,但是当我尝试通过printf%p\n,void*和ram[36]获取ram[36]的地址时,我得到了0x7ffff7ee1024。仍然不是我所期望的。这是在将ram的类型更改为uint8_t*@DavidMcGee之后:如果指针是uint8_t*,那么基址ram=0x7FFFF7EE1000意味着&ram[36]应该是0x7FFFF7EE1024,因为十六进制24==dec 36。