[英]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指令,也無需更改結構中元素的順序。
您基本上有以下選擇:
__attribute__((packed))
或類似方法來填充編譯器插入的控件填充(推薦,但要求您使用編譯器擴展名) 在不使用結構的情況下,以字節級別手動訪問。 例如:
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.