C/C++程序崩溃原因分析

概述

我们运行程序时经常会遇到异常崩溃,也就是我们常说的crash,下面我想总结一下crash出现的原因。而导致crash的主要原因就是段错误(Segmentation Fault)是不是很熟悉,相信每个运行过C程序的小伙伴都见过这两个单词,而且这种错误一般不给其他提示,看着很纠结。导致段错误的原因一般有

1.尝试访问我们系统中不存在的内存位置
2.试图在只读存储位置上进行写操作。

第一种原因就是字面意思,我想也不用解释了吧,比较常见一种情况是对空指针的读取操作。我们来看下第二种,举个小例子:

int main() 
{
          
    
	char *str = "crash";	 
	*(str+1) = n; 
	return 0; 
}

执行上面的代码就是报错:Segmentation fault (core dumped) 在代码中我们定义了字符串常量str,然后我们试图在字符串中加入一个字母n。我们知道字符串在内存中是作为常量保存的,就类似于数字0.1.2…,假设把“crash”看做数字0,n看做1,上面的行为就类似于给数字本身赋值,0 = 1,我们知道这种赋值是非法的。

3.试图访问受保护的内存位置, 例如内核内存
4.内存耗尽

4.1 堆栈溢出:发生不终止的内存位置递归的情况。

#include<stdio.h> 
  
void fun(int x) 
{
          
    
    if (x == 1) 
       return; 
    x = 6; 
    fun(x); 
} 
  
int main() 
{
          
    
   int x = 5; 
   fun(x); 
}

4.2 内存泄漏: 如果我们通过某个程序动态申请一些内存,但是用完后没有及时释放。当下次我们再调用这个程序时又会申请一次内存(请注意因为上一次申请的内存没有释放,所以我们以为只是使用第二次申请的内存,但是系统会认为两次申请的内存我们都在使用,因此第一次申请的内存还是处于被占用状态)多次调用程序之后,内存就会被耗尽,就会出现动态申请内存失败,程序就会crash。

int main() 
{
          
    
    for (int i=0; i<10000000; i++) 
    {
          
    
       int *ptr = (int *)malloc(sizeof(int)); 
    } 
}
5.缓冲区溢出

相信越界这个词大家都听过,其中最为常见的就是数组越界。

#include <stdio.h> 
  
int main() 
{
          
    
    char A[4] = "";  
    strcpy(A, "crash"); 
    return 0; 
}
6.除以零

整数除以零默认的处理方式是终止进程 有点数学常识的都知道整数除以0是不允许的,在计算机中也是,这种情况其实出现的很少,但一旦出现,又很难被发现,所以 在做整数除法时,要判断被除数是否为0的情况。

经验分享 程序员 微信小程序 职场和发展