the*_*ith 7 c memory function-pointers memcpy bus-error
我们在这里处理C. 我只是想到了这个想法,想知道是否有可能访问存储函数的内存中的点foo,并将函数的内容复制到内存中的另一个点.具体来说,我正在努力让以下工作:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void foo(){
printf("Hello World");
}
int main(){
void (*bar)(void) = malloc(sizeof foo);
memcpy(&bar, &foo, sizeof foo);
bar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但运行它会导致总线错误:Bus error: 10.我试图将函数的内容复制foo到一个内存空间bar然后执行新创建的函数bar.
除了查看这样的事情是否可能之外,没有其他原因可以揭示C语言的复杂性.我没想到它有什么实际用途.
我正在寻找指导让这个工作,或以其他方式被告知,有理由,为什么这不起作用
编辑查看一些答案并了解读取,写入和可执行内存,我突然意识到可以通过写入可执行内存来在C中动态创建函数.
使用标准C,您尝试执行的是实现定义的行为,并且无法移植.在给定的平台上,您可以使这项工作成功.
内存malloc给你通常不可执行.跳到那里会导致总线错误(SIGBUS).假设您在类似POSIX的系统上,为函数分配内存mmap和使标志导致内存区域可执行或用于mprotect将区域标记为可执行.
你还需要更加小心你提供的内存量,你不能简单地采用函数的大小,并期望它是函数的长度,sizeof不是为了提供这种功能.您需要使用其他方法找出函数长度.
在现代桌面上,虚拟内存管理器会妨碍您.内存区域有三种访问类型:读取,写入和执行.在代码段仅具有执行权限的系统上,memcpy将失败并出现总线错误.在更典型的情况下,只有代码段具有执行权限,您可以复制该函数,但不能运行,因为包含的内存区域bar将没有执行权限.
此外,确定功能的大小是有问题的.考虑以下程序
void foo( int *x )
{
printf( "x:(%zu %zu) ", sizeof x, sizeof *x );
}
int main( void )
{
int x = 0;
foo( &x );
printf( "foo:(%zu %zu)\n", sizeof foo, sizeof *foo );
}
Run Code Online (Sandbox Code Playgroud)
在我的系统上,输出x:(8 4) foo:(1 1)表明获取sizeof函数指针或函数本身不是受支持的操作.