根据this伯克利课程和this斯坦福大学课程,将int
分配给pointer
这样的课程会导致我的课程崩溃:
#include<stdio.h>
int main() {
int *p;
*p = 5;
printf("p is %d\n", *p);
return 0;
}
然而,当我使用GCC {Apple LLVM 5.0(clang-500.2.79)(基于LLVM 3.3svn)在OSX 10.9.2上编译时,我得到以下输出:
Chris at iMac in ~/Source
$ ./a.out
p is 5
为什么?我看到了相反的问题(Allocating a value to a pointer in c),但这只会让我更加困惑,因为我的程序几乎与该问题中发布的代码相同。
答案 0 :(得分:2)
您没有将int
分配给pointer
。如果p
是指针,则*p
指向其值。您正在为整数赋值分配*p = 5;
,它是普通整数。
在这种情况下,p
未初始化,可能会导致分段错误。
答案 1 :(得分:1)
我的回答:你很幸运! 事实是,你碰巧在p中的值是一个有效的内存地址,你可以实际写入,这就是它工作的原因......
尝试在编译器中使用优化选项(-O3),而不是获得不同的结果......
答案 2 :(得分:1)
您的计划不能保证失败,也不能保证成功。您正在取消引用可以保存任何地址的指针。这是未定义的行为。
答案 3 :(得分:1)
根据伯克利的这个课程和斯坦福大学的课程,给像这样的指针分配一个int会导致程序崩溃:
首先,让我们的术语正确无误。你不是“为指针分配int
”。 分配是存储位置的创建。 int
是值。指针是值。 指针可以解除引用。取消引用有效指针的结果是生成存储位置。取消引用无效指针的结果是未定义的,并且可以直接执行任何。值可以分配到存储位置。
所以你有:
int *p;
您已分配一个名为p
的(短期)存储位置。该存储位置的值是一个指针。由于您没有将其初始化为有效指针,因此其值是有效指针或无效指针;这是什么?这取决于你的编译器来决定。它可能总是无效的。它总是有效的。或者它可能是偶然的。
然后你有:
*p = 5;
您取消引用指针以生成存储位置,然后您在该存储位置卡住了5。如果它是一个有效的指针,恭喜你,你把5卡在一个有效的存储位置。如果它是一个无效的指针,那么你有未定义的行为;再次,任何事情都可能发生。
printf("p is %d\n", *p); // 5!
显然你很幸运,这次它是一个有效的存储位置。
根据这个伯克利课程和斯坦福大学的课程[这]应该会导致我的课程崩溃:
然后这些课程是错误的,或者你错误地引用它们或误解它们。该程序允许执行任何内容。允许发送电子邮件邀请伊朗总统参加您的电影之夜,允许打印任何内容,允许其崩溃。它不是必需做任何事情,因为“允许做任何事情”和“需要做某事”是对立。
答案 4 :(得分:0)
并不是应该崩溃,而是未定义的行为。
根据系统和运行时的情况,分配到解除引用和未初始化的指针可以是段错误或继续“正常”运行,也就是说它看似有效但可能有不寻常的副作用。