簡體   English   中英

使用結構指針訪問mmap區域

[英]accessing mmap region using structure pointer

如果我通過具有孔的結構類型的指針訪問文件的內存映射,則可能無法將結構元素映射為正確的數據。 例如。

#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>

typedef union{
    int a;
    char c[4];
}INT;

typedef struct{
    char type;
    INT data;
}RECORD;

int main(){
    int fd;
    RECORD *recPtr;
    fd = open("./f1", O_RDWR);
    if (fd == -1){
            printf("Open Failed!\n");
    }
    printf("Size of RECORD: %d\n", sizeof(RECORD));
    recPtr = (RECORD *)mmap(0, 2*sizeof(RECORD), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (recPtr == MAP_FAILED){
            printf("Map Filaed!\n");
    }
    printf("type: %c, data: %c%c%c%c\n", recPtr->type, recPtr->data.c[0], recPtr->data.c[1], recPtr->data.c[2], recPtr->data.c[3]);
}

如果文件“ f1”包含以下數據:

012345678

上面的程序給出的輸出為

Size of RECORD: 8
type: 0, data: 4567

因為字符123被結構孔吞噬。

有沒有一種方法可以避免這種情況,而無需使用pragma pack指令,也無需更改結構中元素的順序。

您基本上有以下選擇:

  1. 接受填充。 只要您的數據不需要跨體系結構可移植,這很好(也是最快的選擇)。
  2. 使用__attribute__((packed))或類似方法來填充編譯器插入的控件填充(推薦,但要求您使用編譯器擴展名)
  3. 在不使用結構的情況下,以字節級別手動訪問。 例如:

     char type; int data; memcpy(&type, ((char *)recPtr), 1); memcpy(&data, ((char *)recPtr) + 1, sizeof(data)); 

將二進制數據直接讀入結構是災難的根源。 這意味着您正在對某些輸入的結構進行假設,而無需驗證; 當然,您之后可以檢查結構的完整性。 但是通常,您將不得不對輸入數據進行與體系結構有關的調整。 想想低端與大端。 不同的字長,打包規則等

長話短說:不要陷入陰暗面,這是快速黑客的誘人承諾。

讀取文件的唯一正確方法是逐個八位位組讀取文件。 您當然可以在緩沖區中讀取較大的塊,但是您應該通過查看每個位來處理它們。 如果您擔心性能,則應閱讀第1卷以及“計算機編程的藝術”第4卷的最新內容,該書深入解釋了如何有效地處理數據流而不忽略任何數據。

或使用Google的協議緩沖區。

暫無
暫無

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

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