C指针(始终)是否从有效的地址存储器开始?例如,如果我有以下代码:
int *p;
*p = 5;
printf("%i",*p); //shows 5
为什么这段代码起作用?根据我读过的书,他们说一个指针总是需要一个有效的地址存储器,并给出以下和类似的示例:
int *p;
int v = 5;
p = &v;
printf("%i",*p); //shows 5
答案 0 :(得分:5)
C指针(总是)从有效的地址存储器开始吗?
否。
为什么此代码有效?
该代码调用未定义的行为。如果它看起来可以在具有特定编译器选项的特定系统上运行,那只是一个巧合。
答案 1 :(得分:3)
不。未初始化的局部变量具有不确定的值,在对其求值的表达式中使用它们会导致未定义的行为。
答案 2 :(得分:2)
该行为是不确定的。 AC编译器可以优化指针访问,并注意到事实中p
未被使用,仅使用对象*p
,并替换了{ {1}}与*p
并有效地产生与该源代码相对应的程序:
q
使用GCC 7.3.0和#include <stdio.h>
int main(void) {
int q = 5;
printf("%i", q); //shows 5
}
开关编译程序时就是这种情况-不会崩溃。如果我在没有优化的情况下对其进行编译,则会崩溃。这两个程序都是对代码的符合标准的解释,即,取消引用 not 指向有效对象的指针具有未定义的行为。 / p>
答案 3 :(得分:0)
否。
在较早的时候,通常会初始化指向选定内存地址的指针(例如,链接到硬件)。
char *start_memory buffer = (char *)0xffffb000;
编译器无法找到这是否是有效地址。这涉及演员,所以很欺骗。
考虑
static int *p;
p
将具有NULL值,该值不指向有效地址(Linux,但是在内核上,它使该地址无效,其他操作系统可以使用&NULL
上的内存来存储一些数据。
但是您也可以创建初始化变量,因此使用未定义的初始值(这可能是错误的)。