我正在尝试使用 mmap 分配内存,这是代码:
long long *copy;
copy = (long long*)mmap(NULL,
(size_t)1024,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANON, -1, 0);
if (copy == MAP_FAILED) {
fprintf(stderr, "Memory allocation failed (Process aborted)n");
exit(1);
}
printf("Pointer: %pn", copy);
显然,我检查分配是否失败。发生这种情况时,我应该从从手册页收集的内容中得到 -1。问题是我得到-12,0xfffffffffffffff4
,所以没有捕获错误并且程序继续。我想也许是因为(long long*)
强制转换,但强制转换不应该改变指针值。所以我很好奇为什么会发生这种情况以及如何防止它。
更奇怪的行为:
我试图打印errno
.如果我使用printf("%dn", errno);
它会打印 0,指针仍设置为0xfffffffffffffff4
.但是如果我使用err(errno, "%p", copy);
那么它会打印:
program.exe: 0x7f8130981000: Success
现在指针有效,但我无法使用它,因为err
终止了执行。
在编译所有警告(-Wmissing-prototypes -Wstrict-prototypes -Werror -Wextra
(时,正如评论中所建议的那样,我意识到<err.h>
不包括在内。当我把它包括在内时,我在问题末尾描述的"奇怪行为"消失了;该程序运行正常,但指针仍然不好,我不知道,但是如果我不检查errno
,该程序就可以工作了。
在代码的其他一些部分,我有汇编编写的函数,这些函数一直运行良好(这就是为什么我认为错误与它们无关(。但后来我记得他们中的一些人使用%rbx
在他们之间传递信息,但碰巧%rbx
是用于 gcc 中errno
的寄存器。
因此,查看该函数生成的汇编代码,我意识到%rbx
不受编译器的"保护"。添加到标题<errno.h>
修复了这个问题,现在一切正常。
尽管它似乎在没有适当的包含的情况下工作,但这绝对是一个要更加小心并始终使用最大警告选项的教训。