function占用内存空间吗?

void demo() { printf("demo"); } int main() { printf("%p",(void*)demo); return 0; } 

上面的代码打印了函数demo的地址。
因此,如果我们可以打印函数的地址,这意味着该函数存在于内存中并占用其中的一些空间。
那么它在内存中占据了多少空间?

因此,如果我们可以打印函数的地址,这意味着该函数存在于内存中并占用其中的一些空间。

是的,您编写的函数将编译为存储在内存中的代码。 (在解释语言的情况下,代码本身保存在内存中并由解释器执行。)

那么它在内存中占据了多少空间?

内存量完全取决于function。 你可以写一个很长的函数或一个很短的函数。 长的将需要更多的内存。 用于代码的空间通常不是您需要担心的事情,除非您在具有严重内存限制的环境中工作,例如在非常小的嵌入式系统上。 在具有现代操作系统的台式计算机(甚至移动设备)上,虚拟内存系统将根据需要将代码页移入或移出物理内存,因此代码消耗的可能性也很小。很多记忆。

您可以使用objdump -r -d自己查看:

 0000000000000000 : 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: bf 00 00 00 00 mov $0x0,%edi 5: R_X86_64_32 .rodata 9: b8 00 00 00 00 mov $0x0,%eax e: e8 00 00 00 00 callq 13  f: R_X86_64_PC32 printf-0x4 13: 5d pop %rbp 14: c3 retq 0000000000000015 
:

编辑

我拿了你的代码并编译(但没有链接!)它。 使用objdump您可以看到编译器列出要运行的代码的实际方式。 在一天结束时,没有一个function:对于CPU而言,它只是跳转到某个位置(在此列表中恰好标记了)。 因此“函数”的大小是包含它的代码的大小。


似乎有些混淆,这在某种程度上不是“真正的代码”。 这是GDB所说的:

 Dump of assembler code for function demo: 0x000000000040052d <+0>: push %rbp 0x000000000040052e <+1>: mov %rsp,%rbp 0x0000000000400531 <+4>: mov $0x400614,%edi 0x0000000000400536 <+9>: mov $0x0,%eax 0x000000000040053b <+14>: callq 0x400410  0x0000000000400540 <+19>: pop %rbp 0x0000000000400541 <+20>: retq 

这是完全相同的代码,具有完全相同的大小,由链接器修补以使用实际地址。 gdb以十进制打印偏移,而objdump使用更有利的hex。 如您所见,在这两种情况下,大小为21个字节。

当然它占用了内存空间,整个程序在执行后会加载到内存中。 通常,程序指令存储在存储空间的最低字节中,称为text section 。 你可以在这里阅读更多相关内容: http : //www.geeksforgeeks.org/memory-layout-of-c-program/

是的,您在代码中使用的所有函数都占用了内存空间。 但是,内存空间不一定完全属于您的function。 例如, inline函数将占用每个函数内部的空间,从中调用它。

该标准没有提供一种方法来告诉函数在内存中占用多少空间,因为指针算法是一种允许您计算数据存储器中连续内存区域大小的技巧,它没有为函数指针定义。 此外,ISO C禁止将函数指针转换为对象指针类型,因此您无法通过将函数指针转换为char*来解决此限制。

 printf("%p",demo); 

上面的代码打印函数demo()的地址。

这是未定义的行为: %p期望void* ,而您传递void (*)() 。 您应该看到编译器警告,告诉您正在执行的操作无效( 演示 )。

至于确定它占用的内存量,这在运行时是不可能的。 但是,还有其他方法可以确定它: 如何以字节为单位获取函数的长度?

这些函数被编译成机器代码,只能在特定的ISA上运行(x86,如果它将在手机上运行,​​可能是ARM等)。因为不同的处理器可能需要更多或更少的指令来运行相同的function,并且长度指令也可能有所不同,在编译之前,无法事先知道函数的大小。

即使您知道要编译的处理器和操作系统,不同的编译器也会根据它们使用的指令以及它们如何优化代码来创建函数的不同等效表示。

另外,请记住,函数以不同的方式占用内存。 我想你在谈论代码本身,这是它自己的部分。 在执行期间,该函数还可以占用堆栈上的空间 – 每次调用该函数时,都会以堆栈帧的forms占用更多内存。 数量取决于函数声明的局部变量和参数的数量和类型。

是的,但是你可以将它声明为内联,因此编译器将获取源代码并将其移动到您调用该函数的位置。 或者您也可以使用预处理器宏。 虽然请记住使用内联将生成更大的代码,但它会更快地执行,并且编译器可以决定忽略您的内联请求,如果它感觉它会变得很大。