我正在学习函数指针,我了解到我们可以使用函数指针指向函数。那么我假设它们会留在内存中,它们留在堆栈(stack)还是堆(heap)中呢?我们能计算它们的大小吗?
我正在学习函数指针,我了解到我们可以使用函数指针指向函数。那么我假设它们会留在内存中,它们留在堆栈(stack)还是堆(heap)中呢?我们能计算它们的大小吗?
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 ;
}
函数属于文本段(可能是堆内存或其等效物)或您使用的架构的等效物。编译后无法获得有关函数大小的数据,最多只能从符号表获取它们的入口点(该符号表不一定可用)。因此,在大多数C环境中,您无法实际计算它们的大小。
它们(通常)与堆栈或堆是分离的。
有方法可以找到它们的大小,但它们中没有一个是全平台可移植的。如果您认为需要/想知道大小,则很可能正在做一些应该避免的事情。
void *x; std::cout << sizeof(*x);
不应该被编译--但是在gcc中,它会编译并打印出1
。 - Jerry Coffin有一个有趣的方法来发现函数的大小。
#define RETN_empty 0xc3
#define RETN_var 0xc2
typedef unsigned char BYTE;
size_t FunctionSize(void* Func_addr) {
BYTE* Addr = (BYTE*)Func_addr;
size_t function_sz = 0;
size_t instructions_qt = 0;
while(*Addr != (BYTE)RETN_empty && *Addr != (BYTE)RETN_var) {
size_t inst_sz = InstructionLength((BYTE*)Addr);
function_sz += inst_sz;
Addr += inst_sz;
++instructions_qt;
}
return function_sz + 1;
}
objdump -t -i .text a.out
来获取它,其中a.out是您二进制文件的名称。.text
是链接器放置代码的位置,加载器可以选择使此内存只读(甚至仅执行)。如果需要,在之前的帖子中已经有人回答了这个问题,有方法可以做到这一点,但这很棘手且不可移植... Clifford提供了最直接的解决方案,但链接器很少将函数以这种连续的方式放入最终二进制文件中。另一种解决方案是在链接器脚本中使用编译指示符定义部分,并保留用于全局变量的存储空间,链接器将使用包含您的函数的SIZEOF(...)部分填充该变量。这取决于链接器,而不是所有链接器都提供此功能。如上所述,函数大小是由编译器在编译时生成的,并且所有大小在链接时都为链接器所知。如果您绝对必须这样做,可以让链接器输出一个包含起始地址、大小和名称的映射文件。然后您可以在运行时解析此代码。但我认为没有一种可移植、可靠的方法来在运行时计算它们,而不超出C的范围。
Linux内核也类似地用于运行时分析。
C语言没有垃圾回收器。拥有指向某个东西的指针并不意味着它会一直存在于内存中。
函数总是在内存中,无论您是否使用它们,无论您是否保留对它们的指针。
动态分配的内存可以被释放,但这与保留指向它的指针无关。您不应该保留已释放的内存的指针,并且在失去指向它的指针之前应该将其释放,但语言不会自动执行此操作。
如果有什么东西像函数的大小,它应该是它的堆栈帧大小。或者更好的是,请尝试思考一下,按照您的理解,函数的大小应该是多少?你是指它的静态大小,也就是当所有操作码加载到内存中时的大小吗?如果是这样,那么我没有看到任何语言提供的查找该大小的特性。也许你要寻找一些黑客方法。可能有很多,但我没有尝试过。
#include<stdio.h>
int main(){
void demo();
int demo2();
void (*fun)();
fun = demo;
fun();
printf("\n%lu", sizeof(demo));
printf("\n%lu", sizeof(*fun));
printf("\n%lu", sizeof(fun));
printf("\n%lu", sizeof(demo2));
return 0;
}
void demo(){
printf("tired");
}
int demo2(){
printf("int type funciton\n");
return 1;
}
$ nm filename.o
或$ nm filename.obj
命令,然后查看“text”部分,这是十六进制的... - Yousha Aleayoub