- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
在 C(或 C++)中,如果指针的值为零,则它们是特殊的:建议我在释放内存后将指针设置为零,因为这意味着再次释放指针并不危险;当我调用 malloc 时,如果它无法获取内存,它会返回一个值为 0 的指针;我一直使用 if (p != 0)
来确保传递的指针是有效的,等等。
但是既然内存寻址从 0 开始,那么 0 不就和其他地址一样是有效地址吗?如果是这种情况,如何使用 0 来处理空指针?为什么不是负数 null 而不是?
编辑:
一堆很好的答案。我会根据我自己的想法来总结所表达的答案中所说的内容,如果我有误解,希望社区能够纠正我。
就像编程中的其他一切一样,它是一种抽象。只是一个常量,与地址 0 没有真正的关系。C++0x 通过添加关键字 nullptr
来强调这一点。
它甚至不是地址抽象,它是 C 标准指定的常量,编译器可以将其转换为其他数字,只要它确保它永远不会等于“真实”地址,并且等于其他 null如果 0 不是用于平台的最佳值,则为指针。
如果它不是一个抽象,就像早期的情况一样,地址 0 被系统使用,并且程序员不受限制。
我承认,我的负数建议有点疯狂。使用有符号整数表示地址有点浪费,如果这意味着除了空指针(-1 或其他)之外,值空间在构成有效地址的正整数和浪费的负数之间平均分配。
如果任何数字总是可以用数据类型表示,那么它就是 0。(可能 1 也是。我想到一位整数,如果无符号则为 0 或 1,或者如果有符号则仅为有符号位,或两位整数,即 [-2, 1]。但你可以选择 0 为空,1 为内存中唯一可访问的字节。)
我心中仍有一些 Unresolved 问题。堆栈溢出问题 Pointer to a specific fixed address 告诉我,即使空指针的 0 是一种抽象,其他指针值也不一定。这导致我发布另一个堆栈溢出问题, Could I ever want to access the address zero? .
最佳答案
2 分:
只有源代码中的常量值 0 是空指针——编译器实现可以在运行代码中使用它想要或需要的任何值。一些平台有一个特殊的指针值,它是“无效的”,实现可能会用作空指针。 C FAQ 有一个问题,"Seriously, have any actual machines really used nonzero null pointers, or different representations for pointers to different types?" ,这指出了几个平台使用 0 的这个属性作为 C 源代码中的空指针,而在运行时以不同的方式表示。 C++ 标准有一个注释明确指出,转换“具有零值的整型常量表达式总是产生空指针,但转换恰好具有零值的其他表达式不需要产生空指针”。
平台可以使用负值作为地址 - C 标准只需要选择一些东西来指示空指针,然后选择零。老实说,我不确定是否考虑了其他哨兵值。
空指针的唯一要求是:
关于c++ - 为什么地址零用于空指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2759845/
我刚接触 C 语言几周,所以对它还很陌生。 我见过这样的事情 * (variable-name) = -* (variable-name) 在讲义中,但它到底会做什么?它会否定所指向的值吗? 最佳答案
我有一个指向内存地址的void 指针。然后,我做 int 指针 = void 指针 float 指针 = void 指针 然后,取消引用它们以获取值。 { int x = 25; vo
我正在与计算机控制的泵进行一些串行端口通信,我用来通信的 createfile 函数需要将 com 端口名称解析为 wchar_t 指针。 我也在使用 QT 创建一个表单并获取 com 端口名称作为
#include "stdio.h" #include "malloc.h" int main() { char*x=(char*)malloc(1024); *(x+2)=3; --
#include #include main() { int an_int; void *void_pointer = &an_int; double *double_ptr = void
对于每个时间步长,我都有一个二维矩阵 a[ix][iz],ix 从 0 到 nx-1 和 iz 从 0 到 nz-1。 为了组装所有时间步长的矩阵,我定义了一个长度为 nx*nz*nt 的 3D 指针
我有一个函数,它接受一个指向 char ** 的指针并用字符串填充它(我猜是一个字符串数组)。 *list_of_strings* 在函数内部分配内存。 char * *list_of_strings
我试图了解当涉及到字符和字符串时,内存分配是如何工作的。 我知道声明的数组的名称就像指向数组第一个元素的指针,但该数组将驻留在内存的堆栈中。 另一方面,当我们想要使用内存堆时,我们使用 malloc,
我有一个 C 语言的 .DLL 文件。该 DLL 中所有函数所需的主要结构具有以下形式。 typedef struct { char *snsAccessID; char *
我得到了以下数组: let arr = [ { children: [ { children: [], current: tru
#include int main(void) { int i; int *ptr = (int *) malloc(5 * sizeof(int)); for (i=0;
我正在编写一个程序,它接受一个三位数整数并将其分成两个整数。 224 将变为 220 和 4。 114 将变为 110 和 4。 基本上,您可以使用模数来完成。我写了我认为应该工作的东西,编译器一直说
好吧,我对 C++ 很陌生,我确定这个问题已经在某个地方得到了回答,而且也很简单,但我似乎找不到答案.... 我有一个自定义数组类,我将其用作练习来尝试了解其工作原理,其定义如下: 标题: class
1) this 指针与其他指针有何不同?据我了解,指针指向堆中的内存。如果有指向它们的指针,这是否意味着对象总是在堆中构造? 2)我们可以在 move 构造函数或 move 赋值中窃取this指针吗?
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: C : pointer to struct in the struct definition 在我的初学者类
我有两个指向指针的结构指针 typedef struct Square { ... ... }Square; Square **s1; //Representing 2D array of say,
变量在内存中是如何定位的?我有这个代码 int w=1; int x=1; int y=1; int z=1; int main(int argc, char** argv) { printf
#include #include main() { char *q[]={"black","white","red"}; printf("%s",*q+3); getch()
我在“C”类中有以下函数 class C { template void Func1(int x); template void Func2(int x); }; template void
我在64位linux下使用c++,编译器(g++)也是64位的。当我打印某个变量的地址时,例如一个整数,它应该打印一个 64 位整数,但实际上它打印了一个 48 位整数。 int i; cout <<
我是一名优秀的程序员,十分优秀!