我正在尝试使用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: %p\n", copy);
显然,我检查分配是否失败。当发生这种情况时,我应该从man pages收集的内容得到-1。事情是我得到-12,好0xfffffffffffffff4
,所以错误没有被捕获,程序继续。我想也许是因为(long long*)
强制转换,但是强制转换不应该改变指针值。所以我很好奇为什么会发生这种情况以及如何防止它。
更奇怪的行为:
我尝试打印errno
。如果我使用printf("%d\n", errno);
它会打印0并且指针仍然设置为0xfffffffffffffff4
。但如果我使用err(errno, "%p", copy);
,则打印出来:
program.exe: 0x7f8130981000: Success
现在指针有效,但由于err
终止执行,我无法使用它。
答案 0 :(得分:0)
根据评论中的建议编译所有警告(.tags-panel
)时,我意识到-Wmissing-prototypes -Wstrict-prototypes -Werror -Wextra
未包括在内。当我把它包括在内时,我在问题的最后描述的“奇怪的行为”消失了;程序运行正常,但仍然有一个坏指针,我不知道它,但在这一点上,如果我没有检查<err.h>
,该程序将起作用。
在代码的其他部分,我有汇编编写的函数,这些函数一直很好用(这就是为什么我认为错误与它们无关)。但后来我记得有些人使用errno
在他们之间传递信息,但恰好%rbx
是gcc中%rbx
使用的寄存器。
所以看一下该函数生成的汇编代码,我意识到errno
没有被编译器“保护”。添加到标题%rbx
修复了它,现在一切正常。
即使它似乎没有适当的包含,但这绝对是一个教训,要更加小心,并始终使用最大警告选项。