我最近(最初從這里)學習了如何使用Cmmap快速讀取檔案,如以下示例代碼所示:
// main.c
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#define INPUT_FILE "test.txt"
int main(int argc, char* argv) {
struct stat ss;
if (stat(INPUT_FILE, &ss)) {
fprintf(stderr, "stat err: %d (%s)\n", errno, strerror(errno));
return -1;
}
{
int fd = open(INPUT_FILE, O_RDONLY);
char* mapped = mmap(NULL, ss.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
fprintf(stdout, "%s\n", mapped);
munmap(mapped, ss.st_size);
}
return 0;
}
我的理解是,這種使用mmap回傳一個指向長度堆分配位元組的指標。
我已經在純文本檔案上對此進行了測驗,這些檔案沒有明確地以空字符結尾,例如帶有 13 位元組 ascii 字串“hello, world!”的檔案:
$ cat ./test.txt
hello, world!$
$ stat ./test.txt
File: ./test.txt
Size: 13 Blocks: 8 IO Block: 4096 regular file
Device: 810h/2064d Inode: 52441 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ user) Gid: ( 1000/ user)
Access: 2022-10-25 20:30:52.563772200 -0700
Modify: 2022-10-25 20:30:45.623772200 -0700
Change: 2022-10-25 20:30:45.623772200 -0700
Birth: -
當我運行我的編譯代碼時,它永遠不會出現段錯誤或產生垃圾——列印未終止的 C 字串的典型癥狀。
當我通過gdb運行我的可執行檔案時,mapped[13]總是'\0'.
這是未定義的行為嗎?
我看不出從輸入檔案進行記憶體映射的位元組如何可靠地以 NULL 終止。
對于一個 13 位元組的字串,我通常會使用的“等效”是malloc分配read一個 14 位元組的陣列,從檔案讀取到記憶體,然后將位元組 13(基于 0)顯式設定為'\0'.
uj5u.com熱心網友回復:
mmap回傳指向內核分配的整個頁面的指標。它沒有通過malloc。頁面通常是每個 4096 位元組,顯然內核用零填充額外的位元組,而不是垃圾。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/520273.html
標籤:Cc字符串地图空终止
上一篇:結構內部元素的值賦值在c中失敗
