📜  堆溢出和堆栈溢出

📅  最后修改于: 2021-05-30 12:06:35             🧑  作者: Mango

堆溢出:

堆是进程的内存区域,用于存储动态变量。这些变量使用malloc()和calloc()函数进行分配,并使用realloc()函数调整大小,这些函数是C的内置函数。可以全局访问这些变量,并且一旦我们在堆上分配了内存,我们就有责任释放该内存空间使用后。有两种情况可能导致堆溢出:

  1. 如果我们连续分配内存,但在使用后没有释放该内存空间,则可能导致内存泄漏–内存仍在使用中,但不可用于其他进程。
    // C program to demonstrate heap overflow
    // by continuously allocating memory
    #include
      
    int main()
    {
        for (int i=0; i<10000000; i++)
        {
           // Allocating memory without freeing it
           int *ptr = (int *)malloc(sizeof(int));
        }
    }
    
  2. 如果我们动态分配大量变量。
    // C program to demonstrate heap overflow
    // by allocating large memory
    #include
      
    int main()
    {
        int *ptr = (int *)malloc(sizeof(int)*10000000));
    }
    

堆栈溢出:

堆栈是进程内存中的一个特殊区域,用于存储函数内部使用的局部变量,通过函数传递的参数及其返回地址。每当声明新的局部变量时,它将被压入堆栈。在该函数完成运行之后,将删除与该函数关联的所有变量,并释放它们使用的内存。用户不需要手动释放堆栈空间。堆栈是后进先出的数据结构。

在我们计算机的内存中,堆栈大小是有限的。如果程序使用的内存空间大于堆栈大小,则将发生堆栈溢出并可能导致程序崩溃。在两种情况下,可能会发生堆栈溢出:

  1. 如果我们声明大量局部变量或声明数组或矩阵或任何较大尺寸的高维数组,可能会导致堆栈溢出。
    // C program to demonstrate stack overflow
    // by allocating a large local memory
    #include
      
    int main() {
      
       // Creating a matrix of size 10^5 x 10^5
       // which may result in stack overflow.
       int mat[100000][100000];
    }
    
  2. 如果函数递归地调用自身无限次,则堆栈将无法存储每个函数调用使用的大量局部变量,这将导致堆栈溢出。
    // C program to demonstrate stack overflow
    // by creating a non-terminating recursive
    // function.
    #include
      
    void fun(int x)
    {
        if (x == 1)
           return;
        x = 6;
        fun(x);
    }
      
    int main()
    {
       int x = 5;
       fun(x);
    }
    

有关详细信息,请参考C程序的内存布局。

想要从精选的最佳视频中学习和练习问题,请查看《基础知识到高级C的C基础课程》。