为什么这些调用具有相同的内存地址?

时间:2014-03-01 19:43:35

标签: c memory

递归调用放在系统堆栈上,这就是我所读过的。但如果这是真的,为什么在下面的程序中我得到所有rec()调用的相同地址。他们不应该在堆栈上有连续的地址吗?

    void rec(int n )
    {

          printf("%d -> %p\n",n,rec);
          if( n ==0 )
                return;
          else
                rec(n-1);

    }

当我在main()代码中调用rec(5)时,它给出了如下输出,

 5 -> 0x4004f4
 4 -> 0x4004f4
 3 -> 0x4004f4
 2 -> 0x4004f4
 1 -> 0x4004f4
 0 -> 0x4004f4

抱歉,如果我的查询太基础了。但我无法提出任何解释,除非是由于某种编译器优化。但我不确定。也请告诉我任何可以帮助我在程序运行时查看程序内存(不是大小,但内容)的工具。

提前致谢!!!

更新:

我在每个电话中添加了一个局部变量i,我得到了我想看到的内容。

  5 -> 0x4004f4 0x7fff507d376c
  4 -> 0x4004f4 0x7fff507d373c
  3 -> 0x4004f4 0x7fff507d370c
  2 -> 0x4004f4 0x7fff507d36dc
  1 -> 0x4004f4 0x7fff507d36ac
  0 -> 0x4004f4 0x7fff507d367c

谢谢你@EVERYONE:)

5 个答案:

答案 0 :(得分:3)

为什么要打印相同的地址?

功能

 void rec(int n )

位于内存的代码部分(只读),并且您正在打印函数所在的相同地址。

查看内存

您可以使用objDumphere就是您使用它的方式。

答案 1 :(得分:1)

不,函数的地址在内存中的某个地方是静态的。在递归调用期间,您在堆栈上推送的是返回地址和函数范围内的所有局部变量。 Here是一个很好的教程。

答案 2 :(得分:1)

在你的功能中,当你说:

printf("%d -> %p\n",n,rec);

您要求函数rec(int)的代码地址。编译器只创建函数的一个副本,所以你看到了这个。没有办法(AFAIK)可以从标准C中访问堆栈中的哪个位置。

答案 3 :(得分:1)

rec是函数,代码中只有一个rec,因此没有理由更改地址

答案 4 :(得分:1)

函数调用确实放在堆栈上,但它们不是函数本身,而是所谓的堆栈帧。它们包含参数,局部变量和返回地址(可能还有更多)。

但是,当您打印rec的地址时,您不会获得当前堆栈帧的地址,而是获取该函数代码的地址。这总是相同的,因为代码本身不会改变。

当您打印局部变量的地址时,您可以看到这有效:

printf("%p -> %p\n", &n, rec);

示例输出:

0028fee0 -> 004016d9
0028fec0 -> 004016d9
0028fea0 -> 004016d9
0028fe80 -> 004016d9
0028fe60 -> 004016d9
0028fe40 -> 004016d9

请注意,虽然第二个指针保持不变(它是函数指针),但第一个指针每次都会更改,因为每个调用中都有一个不同的n - 变量。