全局指针导致分段错误?

Posted

技术标签:

【中文标题】全局指针导致分段错误?【英文标题】:Global pointers cause segmentation fault? 【发布时间】:2010-07-11 23:20:36 【问题描述】:

gcc编译后运行时, 代码

诠释* p; int main() *p = 1;

导致分段错误。

显然,内存位置 p 中包含的内容无法写入。

为什么????

另一方面,

整数q[]; int main() *q = 1;

运行良好。

这是怎么回事?

为什么p只包含只读内存?

【问题讨论】:

当然!所有导致分段错误的全局指针肯定比对指针工作原理的轻微误解更有可能! 【参考方案1】:

第一个示例有一个野生(未显式初始化)指针。因为它不是一个自动变量,所以它被设置为 0,这显然不是你拥有的内存。你可以通过打印出来看到这一点:

printf("%p\n", p)

至于第二个,C99 §6.9.2 实际上是这样举例的:

示例 2 如果在末尾 包含

的翻译单元

int i[];

数组 i 的类型仍然不完整, 隐式初始化程序导致它 有一个元素,该元素设置为零 在程序启动时。

一般来说,具有暂定定义(无初始化器)的对象用 0 进行初始化,对于数组来说,这意味着一个元素值为 0 的 1 元素数组。

【讨论】:

作为一名前 C++ 开发人员,我仍然要问一个问题,为什么 *q = 1 可以“正常”工作 - 运气? 我认为gcc 的警告总结了这一点:warning: array ‘q’ assumed to have one element - 这是有效的 C,还是只是 gcc 慷慨,我不确定。 @Will A:因为他正在使用的编译器可能仍在为数组“q”分配一些内存,或者只是内存中的一个位置(带有 0 个元素)指向内存的可写部分(其余全局变量的存储位置)。因为实际上并没有给数组指定大小,所以我会说这要么是未定义的行为,要么是编译器不兼容(我不确定在这种情况下是哪个)。【参考方案2】:

*p = 1; 导致分段错误,因为它在分配之前没有分配任何内存。

*q = 1;works 因为编译器(Mac OS X 上的 gcc 4.2.1)警告说 q[] 被假定为只有一个元素。

【讨论】:

【参考方案3】:

您的第一个示例导致分段错误,因为您取消引用 NULL。你永远不会用一个值来初始化p,并且因为它是一个全局的它会是NULL。因此,您取消引用 NULL,然后繁荣。

我不确定第二个示例如何有效 - gcc 指出它假设 q 是一个 1 元素数组,这就是它不会爆炸的原因。

【讨论】:

以上是关于全局指针导致分段错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的字符串分配会导致分段错误?

指针初始化导致分段错误

delete[] 运算符在非常简单的情况下导致分段错误

访问全局数组会导致分段错误

尝试在函数内动态分配父指针给子指针会导致分段错误

用指向数组的指针替换衰减的数组导致分段错误