编译器出现Process returned -1073741819 (0xC0000005)以及编译器的异常警告,Linux的段错误总结

一,对空指针的访问

在这里插入图片描述
再贴多一种类似情况,对指针解引用后,操作不属于自己的内存空间(0地址),0地址是不准许
访问的!!!
在这里插入图片描述

二,对只读空间的修改

一种情况是这样的,对只读空间进行修改,也是不允许的,一改就会出错!!!直接崩溃在这里插入图片描述
另外一种就是使用了strcpy强行改变了常量字符串的内容
这种就比较隐蔽了。。。单步调试是一种神器🙂

三,动态内存二次free/delete

(Ⅰ)自己程序的二次delete

我用C++写了链表类,然后将两个链表合并为1个,简单的将第2个链表的尾指针指向了第1个链表的头指针,然后
析构了第二个链表之后,又析构了第一个合并后的链表
,造成了非常隐蔽的double free,令我十分不解,
单步调试也发现不了问题,后来直接打印所有节点的地址,
恍然大悟!!!是二次free,简直了!!!
第一张图是有问题时的情况:
释放的内存地址0083E8A8被释放了2次,第一次释放是析构输出的第一行,第二次是析构输出的最后一行
在这里插入图片描述

第二张图解决了问题
在这里插入图片描述

(Ⅱ)对堆内存的二次delete

vs会直接异常,但是cb里面没有出现异常
在这里插入图片描述

四,free/delete了非动态内存

使用了非动态内存或者使用了不属于自己的内存空间
在这里插入图片描述
对上图的解释:你试图对随机的一个地址111进行delete,这个内存不属于你,可能不是动态内存,但是你却试图释放它,其结果是未知的,往往导致程序崩溃!!

五,数组越界修改(打印可能不会异常)

如果你仅仅是打印出来,可能不会异常,但是,如果你试图修改不属于你的内存空间,
就一定会异常!!
在这里插入图片描述

六,修改不属于自己的内存空间

①修改不属于自己的内存空间,因为其右值未被初始化,指向未知内存**

在这里插入图片描述
注:另外常见的还有strcpy,strncpy,strcat,memset等库函数,如果第一个参数未被初始化,
程序同样崩溃

上图的解决方案:对q进行初始化,让其指向有效的空间,这里我使用了new分配内存空间
,当然你改成char p[4];也是合理的;
图示如下:
在这里插入图片描述
还有一种情况就是如下

char* p;//指向未知内存
scanf("%s",p);//试图修改不属于自己的空间
printf("%s",p);//如果用Clion去debug,断点会一直停在scanf那一行,
               // 报告EXC_BAD_ACCESS!!!!

改正如下:

char* p = new char[100];//如果申请成功,指向有效内存
scanf("%s",p);//试图修改属于自己的空间
printf("%s",p);//ok!!

②数组越界修改也是属于这种类型的异常**

③指针的越界读取访问也会导致异常

#include<iostream>
using namespace std;
class Stu{
private:
	char* name;
public:
	Stu(const char* _name):name(new char[(std::strlen(_name)+1]){
		//省略申请失败的检查
		std::strcpy(name,_name);
	}	
};
void write(Stu* s, int n) {
    ofstream out("C:\\Users\\axin\\Desktop\\b.txt", ios::out);
    for (int i = 0; i < n; i++)
        out.write(reinterpret_cast<char*>(s + i), sizeof(Stu));
        //这个write只是把name指向的首地址,即指针本身的值写进去了文件里面
        //但是会导致读取的时候出现字符串读取异常,所以read出来再cout对象的时候会
        //程序崩溃!!!!
}
void read(Stu* s, int n)
{
    ifstream in("C:\\Users\\axin\\Desktop\\b.txt", ios::in);
    for (int i = 0; i < n; i++)
    {
        in.read(reinterpret_cast<char*>(s + i), sizeof(Stu));
        if ((s+i)->getScore() >= 60) {
            cout << s[i];//间接访问对象的name,由于读取字符串异常,访问异常的指针
            //必然运行崩溃
        }
    }
}
int main()
{
	Stu s[3] = {
        Stu(20190001,"Li",99),
        Stu(20190002,"Zhang",59),
        Stu(20190003,"Zhao",100)
    };
    //write(s, 3);
    //如果事先把对象写入文件,后面只是调用read读取,那么访问对象name的时候就会导致
    //程序崩溃
    read(s, 3);
    return 0;
}

总结

这正是不能把含有string成员的对象写入文件的原因,string内部使用指针管理动态内存
我这个例子也是用动态内存管理,都会出现同样的问题!!!

七,因为编译器实现不同而导致的异常崩溃

Vs2019下:
有一次我写的函数忘记返回了vector,结果程序执行完最后一条代码后,异常崩溃,
后面发现编译器给了一个Warning:不是所有路径都有返回值,然后我写了个return后就
正常了

八,总结

哎,就是非法内存访问错误,各种内存管理和地址的非法访问🤣🤣🤣

最后:觉得有用的请点赞关注一波,别只收藏不点赞呐🤣,谢谢。

参考文章:
百度百科-段错误
作者:杰出天下的一篇文章:段错误

  • 26
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿维的博客日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值