分段错误:为啥?

Posted

技术标签:

【中文标题】分段错误:为啥?【英文标题】:Segmentation Fault: Why?分段错误:为什么? 【发布时间】:2011-03-15 16:50:50 【问题描述】:

我有这段代码可以按预期编译和工作:

#include <iostream>

using namespace std;

int fun(int* p)
    *p = 20;
    return 1;


int main()
    int* number;    
    *number =10;

    cout << "before: "<<*number<<endl;
    fun(number);
    cout << "after: "<<*number<<endl;
    return 1;

虽然以下给出了分段错误:

#include <iostream>

using namespace std;

int fun(int* p)
    *p = 20;
    return 1;


int main()
    int test=1; //ADDITION
    int* number;    
    *number =10;

    cout << "before: "<<*number<<endl;
    fun(number);
    cout << "after: "<<*number<<endl;
    return 1;

我正在使用g++ test.cpp -o test进行编译

谁能解释一下这种行为是从哪里来的?

【问题讨论】:

【参考方案1】:

number 未指向main() 中的有效内存位置。只是程序声明了一个指针number,它可以保存整数类型的地址。但是,它没有分配/初始化为指向任何整数的位置。

int* number = new int;
*number = 10;

由于程序正在管理资源,它应该使用delete返回这些资源。

delete number;

如果幸运的话,这两个程序都会出现分段错误。

【讨论】:

【参考方案2】:

在这两个程序中,您都在取消引用未初始化的指针。在第一个中你很幸运,它没有崩溃。

int* number; // number points to a random location - it's not initalized
*number =10; // You write to a random location

使用这个:

int number;
number = 10;
...
fun(&number);

或者,使用 new 分配 int:

int * number = new int;
*number = 10;
...
delete number; // always delete what you new

【讨论】:

他走运了?实际上他很倒霉,因为一个严重的编程错误通过了。 我同意 Benoit 的观点。对于像这样的 UB 来说,not 崩溃是 unlucky【参考方案3】:

由于int* number 未初始化为有效指针,您的两个程序都有未定义的行为。一个失败而另一个没有失败只是平局的运气。试试

int* number = new int;

【讨论】:

【参考方案4】:
int* number;    
*number =10;

number 是一个指向 int 的指针。您需要分配内存,以便它可以指向有效的内存!

int *number = new int;
*number = 10;

现在很好!

【讨论】:

【参考方案5】:

我认为“int test = 1”在这种情况下没有任何意义。但是,整数指针在初始化时指向一个随机数(表示随机内存位置)。尝试执行以下操作:将出现的 *number = 10 替换为 number = new int(); *数字= 10;当进行这样的初始化时,内存将从堆分配给指针。并且不要忘记使用“delete”操作符删除程序末尾的指针。

【讨论】:

【参考方案6】:

您忘记为number 指针分配空间。发生这种情况时,程序行为是未定义的。碰巧在一种情况下它运行了,但在后一种情况下没有。

要么将变量更改为纯 int,

int number = 10;

或者对他们做一个new

int *number = new int[1];
*number = 10;

【讨论】:

【参考方案7】:

该行为来自如下语句:

int* number;
*number =10;

取消引用未初始化的指针后,您已进入“未定义行为”国家/地区。你在程序的其余部分继续这样做,但是在*number = 10 之后整个事情的行为是未定义的。它可能会起作用,它可能会崩溃,它可能会告诉你 1 + 1 = 15 或其他什么。简单地说:你不能取消引用(或访问后面的数据)未初始化的指针。

干杯,

保罗

【讨论】:

以上是关于分段错误:为啥?的主要内容,如果未能解决你的问题,请参考以下文章

分段错误:为啥?

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

为啥释放内存会导致分段错误?

动态二维数组。为啥是分段错误?

为啥写作主要;在 C 中给出一个段错误

为啥重新声明 std::cout 会导致分段错误?