面试题答案
一键面试系统处理方式
当offset
接近文件末尾且length
使得映射范围超出文件大小,不同系统处理方式可能略有不同。一般来说,超出文件现有大小的映射部分会被初始化为零。例如在Linux系统中,mmap
函数会将超出文件末尾的部分视为匿名内存映射,初始值为零。
C代码中正确处理边界情况的方法
- 获取文件大小:在进行内存映射前,先获取文件的实际大小。可以使用
stat
函数来获取文件状态信息,其中包含文件大小。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
int main() {
int fd;
off_t offset = 1000;
size_t length = 200;
struct stat sb;
void *map_start;
fd = open("your_file.txt", O_RDONLY);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
if (fstat(fd, &sb) == -1) {
perror("fstat");
close(fd);
exit(EXIT_FAILURE);
}
// 检查偏移和长度是否合法
if (offset >= sb.st_size) {
printf("Offset is beyond the end of the file.\n");
close(fd);
exit(EXIT_FAILURE);
}
if (offset + length > sb.st_size) {
length = sb.st_size - offset;
}
map_start = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, offset);
if (map_start == MAP_FAILED) {
perror("mmap");
close(fd);
exit(EXIT_FAILURE);
}
// 在这里使用映射的内存
//...
if (munmap(map_start, length) == -1) {
perror("munmap");
close(fd);
exit(EXIT_FAILURE);
}
close(fd);
return 0;
}
- 检查映射返回值:调用
mmap
函数后,检查其返回值是否为MAP_FAILED
。如果是,说明映射失败,通常是由于参数不合法(如偏移或长度超出文件范围),需要进行相应的错误处理,例如关闭文件描述符并退出程序。 - 调整映射长度:在检查到
offset + length > 文件大小
时,将length
调整为文件大小 - offset
,以确保映射范围在文件实际大小之内。这样可以避免访问未初始化或非法的内存区域,防止程序出现未定义行为。