内存分配给C ++中的函数

时间:2010-08-04 07:01:53

标签: c++ function static

我仍然是C ++新手。刚开始读到类的静态成员函数不是特定于对象的 - 所有对象的成员函数都有一个副本。

现在我脑子里出现了两个问题:

  1. 普通功能和静态功能“仅在内存分配方面”有什么区别?

  2. 如果成员函数包含一些局部变量怎么办?在这种情况下,函数“应该”具有该变量的单独副本 - 特定于调用该函数的对象...如何在C ++中解决此问题?

  3. 谢谢!

4 个答案:

答案 0 :(得分:9)

  

有什么区别   普通功能和静态功能   功能“在记忆方面   仅分配“?

无。除了范围之外,静态函数就像一个全局函数。

即使对于非静态成员函数,也不需要额外的内存。成员函数int C::f(int arg1, int arg2)只是int C__f(C* this, int arg1, int arg2)之类的语法糖。

  

如果成员函数包含,该怎么办?   一些局部变量?在这种情况下   功能“应该”有一个单独的   该变量的副本 - 特定于   调用函数的对象......

该函数的每个调用都有一个局部变量的副本(除非它们是static)。这就是C ++中可能的递归。

  

C ++中如何解决这个问题?

函数调用基于“堆栈帧”。堆栈框架包括:

  • 函数的参数(如果适用,包括隐式this)。
  • 函数中的任何其他非static局部变量。
  • “返回地址”,告诉处理器在完成功能后将在何处继续执行。

每当调用函数时,都会创建一个堆栈帧。当函数是,堆栈帧被破坏。如果以递归方式调用函数,则每个递归级别都会获得自己的堆栈帧。例如,如果你有

int factorial(int n) {
    if (n <= 1)
        return 1;
    else
        return factorial(n - 1) * n;
}

然后当你调用factorial(3)时,会像这样创建一个堆栈框架:

------------------------ stack pointer (SP)
n = 3
RA = <in main()>

当对factorial(2)进行递归调用时,会在堆栈顶部添加一个额外的框架

------------------------ SP
n = 2
RA = <in factorial()>
------------------------
n = 3
RA = <in main()>

另一个递归调用是factorial(1)

------------------------ SP
n = 1
RA = <in factorial()>
------------------------
n = 2
RA = <in factorial()>
------------------------
n = 3
RA = <in main()>

这是递归的基本情况,返回值1存储在寄存器中。函数调用完成后,顶层堆栈帧被销毁,并在保存的返回地址继续执行。

------------------------ SP
n = 2                                      
RA = <in factorial()>
------------------------
n = 3
RA = <in main()>

现在,对factorial(2)的调用可以计算其返回值(2),并且可以销毁另一个堆栈帧:

------------------------ SP
n = 3
RA = <in main()>

最后,我们可以计算原始函数调用的结果(6),并破坏这个堆栈帧。

答案 1 :(得分:4)

  1. 没有区别
  2. 在函数
  3. 的每个调用的堆栈上创建和销毁局部变量

答案 2 :(得分:2)

  1. 我发现不太可能存在差异

  2. 您似乎应该阅读一下堆栈分配之间的区别。这可以很好地了解内存如何在较低但仍处于较高水平的情况下工作。对不起,我现在不能提供更多帮助。

  3. 编辑:太慢了:))

答案 3 :(得分:0)

  1. 确实没有那么大的区别。两者都只存储在内存中一次,当调用非静态方法时,除了所有函数之外,指向当前对象的指针(this指针)被压入堆栈(或存储在ECX中,具体取决于您的编译器)参数。静态函数不需要类的实例,因此它就像常规的C函数一样被调用。

  2. 与使用调用堆栈的C相同。