【发布时间】:2010-07-11 23:20:36
【问题描述】:
gcc编译后运行时, 代码
诠释* p; int main() {*p = 1;}导致分段错误。
显然,内存位置 p 中包含的内容无法写入。
为什么????
另一方面,
整数q[]; int main() {*q = 1;}运行良好。
这是怎么回事?
为什么p只包含只读内存?
【问题讨论】:
-
当然!所有导致分段错误的全局指针肯定比对指针工作原理的轻微误解更有可能!
标签: c
gcc编译后运行时, 代码
诠释* p; int main() {*p = 1;}导致分段错误。
显然,内存位置 p 中包含的内容无法写入。
为什么????
另一方面,
整数q[]; int main() {*q = 1;}运行良好。
这是怎么回事?
为什么p只包含只读内存?
【问题讨论】:
标签: c
第一个示例有一个野生(未显式初始化)指针。因为它不是一个自动变量,所以它被设置为 0,这显然不是你拥有的内存。你可以通过打印出来看到这一点:
printf("%p\n", p)
至于第二个,C99 §6.9.2 实际上是这样举例的:
示例 2 如果在末尾 包含
的翻译单元int i[];
数组 i 的类型仍然不完整, 隐式初始化程序导致它 有一个元素,该元素设置为零 在程序启动时。
一般来说,具有暂定定义(无初始化器)的对象用 0 进行初始化,对于数组来说,这意味着一个元素值为 0 的 1 元素数组。
【讨论】:
gcc 的警告总结了这一点:warning: array ‘q’ assumed to have one element - 这是有效的 C,还是只是 gcc 慷慨,我不确定。
*p = 1; 导致分段错误,因为它在分配之前没有分配任何内存。
*q = 1;works 因为编译器(Mac OS X 上的 gcc 4.2.1)警告说 q[] 被假定为只有一个元素。
【讨论】:
您的第一个示例导致分段错误,因为您取消引用 NULL。你永远不会用一个值来初始化p,并且因为它是一个全局的它会是NULL。因此,您取消引用 NULL,然后繁荣。
我不确定第二个示例如何有效 - gcc 指出它假设 q 是一个 1 元素数组,这就是它不会爆炸的原因。
【讨论】: