繁体   English   中英

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

[英]Memory allocation to functions in C++

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

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

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

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

谢谢 !

普通函数和静态函数“仅在内存分配方面”有什么区别?

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

即使对于非静态成员函数,也不需要额外的内存。 成员函数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. 没有不同
  2. 每次调用函数时,都会在堆栈上创建和销毁局部变量
  1. 我觉得不太可能存在差异

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

编辑:太慢了:)

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

  2. 与C一样,使用调用堆栈。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM