簡體   English   中英

Integer 在使用 mmap 時存儲為不正確的值

[英]Integer stored as incorrect value in when using mmap

我正在編寫一個程序,該程序將使用 mmap 將結構數組寫入文件。 問題是第三個 integer 值(左)未正確存儲。 通過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    

結構填充

那么為什么你沒有得到上述預期的結果呢? 因為編譯器在字 alignment 的結構中添加了填充。 所以在value字段之后有兩個填充字節。 打印出sizeof(Node)來查看。 因此,所有內容實際上都向右移動了兩個字節。 所以實際的預期結果是:

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

這正是您顯示的實際結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM