递归函数使用malloc更快地用完内存

时间:2019-04-02 18:04:56

标签: c

我有以下代码:

int main (void)
{
  k++;
  if (k % 10000 == 0)
    fprintf (stderr, "%d ", k / 10000);
  main ();
  return 0;
}
int main (void)
{
  int *tmp;    
  tmp = malloc (100 * sizeof (int));    
  k++;
  if (k % 10000 == 0)
    fprintf (stderr, "%d ", k / 10000);
  main ();
  return 0;
}

k是一个全局变量,其初始值为0。程序递归地调用自身,直到代码填满堆栈。这两个程序都引起了分割错误。

在第二个堆栈中,堆栈溢出发生得更快。但是,由于malloc函数仅返回一个指针,因此堆栈不应注意到此差异。因为分配了动态内存的堆小于堆栈,分段错误会较早发生吗?

* edit:程序崩溃不是问题,这就是这两个程序的重点。我只想知道为什么第二个代码比第一个代码更早出现分段错误,并且如果我提供的解释有误。 用gcc编译(gcc code -o output

1 个答案:

答案 0 :(得分:2)

假设对rec2()的调用已更改为main(),因此它以与第一个示例相同的方式递归,则第二个示例包含一个局部变量(int * tmp),即第一个例子没有。每次调用仅此一项将占用4或8字节(32位或64位版本)的堆栈空间。您可以将代码更改为int * volatile tmp =(int *)0; ,并且仍然应该以相同的方式失败。在大多数环境中,堆和堆栈是分开处理的,通常堆空间要比堆栈空间大。

更新-在以下代码上使用Visual Studio,具有32位版本的发行版,堆栈溢出之前的最后一个显示为1285,将#if 0更改为#if 1,最后一个显示为642。64位构建时,在两种情况下(带有#if 0或#if 1),最后一个显示都是212,这是因为存储在调用者分配的堆栈中的一个寄存器(rcx,rdx,r8,r9为32个字节)显然用于tmp 。

static int k;

int main()
{
#if 0     /* change to #if 1 to use tmp */
int * volatile tmp = (int *)0;
#endif
    k++;
    if (k % 100 == 0)
        fprintf (stderr, "%d ", k / 100);
    main();
}
相关问题