在C中查找函数的大小

我正在学习函数指针,我知道我们可以使用函数指针指向函数。然后我假设它们保留在内存中。它们是保留在堆栈还是堆中?我们可以计算它们的大小吗?

构建代码时,链接器会静态分配代码空间。 在您的代码由操作系统加载的情况下,OS加载程序从OS请求内存并将代码加载到其中。 类似地,静态数据如其名称所示在此时被分配,如同初始堆栈一样(尽管如果创建了额外的线程,则可以创建更多的堆栈)。

关于确定函数的大小,链接器知道此信息,并且在大多数工具链中,链接器可以创建一个映射文件,其中包括所有静态内存对象的大小和位置(即那些未在运行时实例化的对象)堆栈或堆上的时间)。

在运行时没有保证确定函数大小的方法(并且没有理由这样做)但是如果假设链接器在内存中按顺序找到源代码中相邻的函数,则以下内容可能会给出指示函数的大小:

 int first_function() { ... } void second_function( int arg ) { ... } int main( void ) { int first_function_length = (int)second_function - (int)first_function ; int second_function_length = (int)main - (int)second_function ; } 

但是YMMV; 我在VC ++中试过这个,它只在“Release”版本中提供了有效的结果; “调试”构建的结果没有任何意义。 我建议这项练习仅供参考,没有实际用途。

另一种观察代码大小的方法当然是查看调试器中代码的反汇编。

函数是文本段的一部分(可能是也可能不是“堆”)或它与您使用的体系结构的等效项。 关于它们的大小,没有关于编译的数据,最多可以从符号表(不一定是可用的)获得它们的入口点。 因此,在您遇到的大多数C环境中,您无法在实践中计算它们的大小。

它们(通常)与堆栈或堆分开。

有办法找到它们的尺寸,但它们都没有接近便携式。 如果你认为你需要/想要知道它的大小,你可能应该避免的事情很可能很好。

为简单起见,函数通常不会进入堆栈或堆,因为它们是只读数据,而堆栈和堆是读写存储器。

你真的需要在运行时知道它的大小吗? 如果不是,您可以通过简单的objdump -t -i .text a.out获取它,其中a.out是二进制文件的名称。 .text是链接器放置代码的地方,加载器可以选择将此内存设置为只读(甚至只执行只执行)。 如果是,正如之前的post中回复的那样,有很多方法可以做到,但它很棘手且不可移植…… Clifford给出了最直接的解决方案,但是链接器很少将函数以这样的顺序方式放入最终二进制文件。 另一种解决方案是使用编译指示在链接描述文件中定义部分,并为全局变量保留一个存储空间,该变量将由链接器填充,其中包含您的函数的SIZEOF(…)部分。 它依赖于链接器,并非所有链接器都提供此function。

如上所述,函数大小由编译器在编译时生成,并且链接器在链接时已知所有大小。 如果你绝对必须,你可以让链接器踢出一个包含起始地址,大小,当然还有名称的地图文件。 然后,您可以在运行时在代码中解析此问题。 但我不认为有一种便携,可靠的方法可以在运行时计算它们而不会超越C的界限。

Linux内核对运行时分析使用了类似的function。

C没有垃圾收集器。 指向某个东西不会使它留在记忆中。

无论你是否使用它们,函数总是在内存中,无论你是否使用它们。

可以释放动态分配的内存,但它与保持指针无关。 你不应该保持指向你已经释放的内存的指针,你应该在丢失指针之前释放它,但语言不会自动执行。

如果有类似函数的大小,它应该是它的STACK FRAME SIZE。 或者更好的是,请尽量考虑一下,根据你的具体情况,应该是一个函数的大小? 你的意思是它的静态大小,即它加载到内存中的所有操作码的大小吗?如果这就是你的意思,那么我不会看到它们是任何语言提供的function来找出它。可能你找一些hack.There可以很多。但我没有尝试过。