在C(或C++)中,指针是特殊的,如果它们的值为零:我建议在释放内存后将指针设置为零,因为这意味着再次释放指针并不危险; 当我调用malloc时,如果它无法获取内存,则返回一个值为零的指针; 我一直用if (p != 0)它来确保传递的指针是有效的,等等.
但是,由于内存寻址从0开始,因此有效地址不是0吗?如果是这样的话,0如何用于处理空指针?为什么不是负数而是null?
编辑:
一堆好的答案.我将总结在所表达的答案中所说的内容,因为我自己的思想解释了它,并希望如果我误解,社区将纠正我.
就像编程中的其他一切一样,它是一种抽象.只是一个常量,与地址0并不真正相关.C++ 0x通过添加关键字来强调这一点nullptr.
它甚至不是地址抽象,它是C标准指定的常量,只要它确保它永远不等于"真实"地址,编译器就可以将它转换为其他数字,如果0不是,则等于其他空指针用于平台的最佳价值.
如果它不是抽象,早期就是这种情况,系统使用地址0,程序员不受限制.
我承认,我的负面数字建议是一个狂热的头脑风暴.对地址使用有符号整数有点浪费,如果它意味着除了空指针(-1或其他)之外,值空间在产生有效地址的正整数和刚刚浪费的负数之间均匀分配.
如果任何数字总是可以由数据类型表示,那么它就是0.(也可能是1.我想的是一位整数,如果是无符号则为0或1,或者只有符号的有符号位,或两位整数,将是[-2,1].但是你可以只得0为空,1是内存中唯一可访问的字节.)
还有一些东西在我的脑海里没有得到解决.Stack Overflow问题指向特定固定地址的指针告诉我,即使0表示空指针是抽象,其他指针值也不一定.这导致我发布另一个Stack Overflow问题,我是否可以访问地址零?.
我知道当你在C程序中做某些事情时,结果是不确定的.但是,编译器不应该生成无效(机器)代码,对吧?如果代码做错了,或者代码生成了段错误或其他什么,那将是合理的......
这应该是根据编译器规范发生的,还是编译器中的错误?
这是我正在使用的(简单)程序:
int main() {
char *ptr = 0;
*(ptr) = 0;
}
Run Code Online (Sandbox Code Playgroud)
我正在编译-O3.那不应该生成无效的硬件指令,对吧?有了-O0,我在运行代码时遇到了段错误.这看起来更加明智.
编辑:它正在生成一条ud2指令......
我正在为 Linux 编写一个静态程序加载器,我正在读取 ELF 程序头并将段映射到内存。
我遇到过一个可执行文件,它假定其第一个段的虚拟地址为 0。我的内存映射失败,在地址分配虚拟页时出错0。
我想知道是否可以在0用户空间的地址处分配所有内存。
请参阅此示例代码:
/*mmaptests.c*/
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
int main()
{
void* p = mmap(0, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
printf("mmap result %p (errno %s)\n",p,strerror(errno));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我用以下方法编译它:
gcc mmaptests.c
Run Code Online (Sandbox Code Playgroud)
这是它返回的内容:
$./a.out
mmap result 0xffffffffffffffff (errno Operation not permitted)
Run Code Online (Sandbox Code Playgroud)
我将很高兴获得任何见解。
谢谢B