c - 使用 mmap 时整数存储为不正确的值

标签 c binaryfiles mmap

我正在编写一个程序,该程序将使用 mmap 将结构数组写入文件。问题是第三个整数值(左)没有正确存储。当通过od查看文件时,left中的字节似乎向左移动了一个字节。例如...

|loc            |value  |left          |right          |extra bytes?
001 000 000 000 103 120 000 000 000 003 000 000 000 004 000 000 //expected
001 000 000 000 103 120 000 000 003 000 000 000 004 000 000 000 //result
typedef struct{
    int32_t loc;
    char value[2];
    int32_t left;
    int32_t right;

}Node;

Node newNode(int i);

int main(int argc, char *argv[])
{
    int i;
    int fd;
    int result;
    Node *map;  /* mmapped array of int's */

    int filesize = strtol(argv[2], NULL, 10) * sizeof(Node);
    int numvalues = filesize / sizeof(Node);

    fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
    if (fd == -1) {
        perror("File failed to open");
        exit(1);
    }

    //I dont know why this makes it work but we need to move the file pointer around for some reason.
    result = lseek(fd, filesize-1, SEEK_SET);
    if (result == -1) {
        close(fd);
        perror("Error calling lseek()");
        exit(2);
    }

    // same with this
    result = write(fd, "", 1);

    /* Now the file is ready to be mmapped.
    */
    map = (Node *) mmap(0, filesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (map == MAP_FAILED) {
        close(fd);
        perror("Error mmapping the file");
        exit(4);
    }


    for (i = 0; i <numvalues; ++i) {
        map[i] = newNode(i);         /* here is where I save the data */
    }

    munmap(map, filesize);
    close(fd);
    return 0;
}

Node newNode(int i) { /*This method is where the structs are made*/
    Node n;
    n.left = i * 2 + 1;
    n.right = i * 2 + 2;
    n.value[0] = (char)(rand() % ('A' - 'Z') )+ 'A';
    n.value[1] = (char)(rand() % ('A' - 'Z') )+ 'A';
    n.loc = i;

    printf("%d, %d, %c, %c, %d\n", n.left, n.right, n.value[0], n.value[1], n.loc);

    return n;
}

另外,为什么有些整数保存为小端,而另一些整数保存为大端。

最佳答案

您遇到了两个问题:字节顺序和结构填充。

字节序

看来您的系统是小尾数法。这意味着首先存储最低有效字节。我们可以从 1 存储为 01 00 00 00 的事实中看到这一点。在大端系统中,它将是 00 00 00 01。这意味着您的“预期”结果不正确。应该如下。请注意,左右字节已交换。

|loc            |value  |left          |right          |
001 000 000 000 103 120 003 000 000 000 004 000 000 000    

结构填充

那么为什么没有得到上面预期的结果呢?因为编译器在结构体中添加了填充以进行字对齐。所以在value字段之后有两个填充字节。打印出 sizeof(Node) 来查看。因此,所有内容实际上都右移了两个字节。所以实际的预期结果是:

|loc            |value  |pad     |left           |right          |
001 000 000 000 103 120  000 000 003 000 000 000 004 000 000 000    

这正是您所显示的实际结果。

关于c - 使用 mmap 时整数存储为不正确的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61299100/

相关文章:

c - 将数据保存到二进制文件

c - 如何从文本文件中使用 mmap 读取 double 组

free - malloc 实现会将释放的内存返回给系统吗?

c - 为什么在可执行语句后声明变量不适用于 MS C 编译器?

blob - 二进制文件和 BLOB 之间的区别

c++ - 如何截断 XMM 寄存器中的浮点值

swift - 以 1024 字节为单位读取大型二进制数据文件

python mmap 正则表达式在两个文件中搜索公共(public)条目

c - 跳过 C 中的 Scanf 语句

c - 如何解决 fatal error LNK1000 : Internal error during IncrBuildImage?