📜  卡住溢出 (1)

📅  最后修改于: 2023-12-03 15:37:03.798000             🧑  作者: Mango

卡住溢出

什么是卡住溢出

卡住溢出是指程序在进行特定操作时,由于数据量过大或计算精度不够等原因导致程序运行崩溃或无法进行下一步操作的情况。

常见的卡住溢出
栈溢出

栈溢出是指程序在使用栈空间时,由于申请的空间超过栈的容量或栈深度过深导致程序异常。

void recursion(){
    char big_array[10000];
    recursion();
}
int main(){
    recursion();
    return 0;
}

在上述代码中,recursion()函数不断调用自身,并在每次调用时声明大数组big_array,由于每次调用都是在栈空间上进行的,所以程序最终会把所有的栈空间占用完,从而导致栈溢出。

缓冲区溢出

缓冲区溢出是指程序在向缓冲区中写入数据时,由于数据量过大或写入位置不当等原因导致缓冲区溢出的情况。

char buffer[10];
strcpy(buffer, "Hello World!");

在上述代码中,我们尝试向一个长度为10的字符数组buffer中复制一个长度为12的字符串“Hello World!”,这将导致buffer中的第11个位置和第12个位置被overflow了。

整数溢出

整数溢出是指程序在进行整数运算时,由于数据范围过大超过了变量类型的最大值导致计算结果不正确的情况。

short a = 32767;
a = a + 1;   

在上述代码中,定义了一个short类型变量a并初始化为32767,然后在进行a+1的操作时,a将溢出变为-32768,这是由于short类型最大值为32767,加1后超出了其最大值,会被截断为-32768。

如何防止卡住溢出
栈溢出

防止栈溢出的方法包括:

  • 使用HEAP进行分配大空间的变量;
  • 减少程序的递归调用深度;
  • 减少单个函数汇编代码的大小。
void recursion(){
    char *big_array = (char*) malloc(sizeof(char)*10000);
    recursion();
    free(big_array);
}
int main(){
    recursion();
    return 0;
}

在上述代码中,我们使用了malloc动态分配内存来申请存储数据的空间,从而避免使用栈空间,可以有效地防止栈溢出。

缓冲区溢出

防止缓冲区溢出的方法包括:

  • 对输入的数据进行检查并过滤掉异常数据;
  • 在使用strcpy等函数进行字符串复制操作时,对目标缓冲区大小进行检查,避免溢出;
  • 使用strncpy,memcpy等安全的函数进行字符串复制或字节复制操作。
char buffer[10];
strncpy(buffer, "Hello World!", 10);

在上述代码中,我们使用了strncpy函数来将字符串“Hello World!”复制到长度为10的缓冲区中,从而避免了缓冲区溢出的问题。

整数溢出

防止整数溢出的方法包括:

  • 根据数据的范围选择合适的变量类型;
  • 在对变量进行运算之前,先进行数据边界检查。
short a = 32767;
if (a < SHRT_MAX)
    a = a + 1;   

在上述代码中,我们在进行a+1的操作之前,先进行了a与short类型最大值SHRT_MAX的比较,从而避免了整数溢出的问题。

总结

卡住溢出是程序开发过程中常见的问题之一,对于程序员来说,学习如何防止和解决卡住溢出的问题非常重要,避免程序出现卡顿甚至是崩溃的情况。在程序开发过程中,我们应该谨慎地处理数据的类型和范围,避免使用过长的栈空间,对输入数据进行检查和过滤,避免在不安全的函数中使用字符串复制,等等。