在之前不使用malloc分配内存的情况下执行memcpy

在之前不使用malloc分配内存的情况下执行memcpy,c,memcpy,dlopen,C,Memcpy,Dlopen,我在问自己,当我没有为fptr分配内存时,为什么这段代码工作得很好。我希望它有一个未定义的行为,因为执行memcpy时没有为fptr或 struct conf *pconf = NULL; void (*fptr)(char *, struct conf **); void *temp = dlsym(dlptr, "config_run_all"); memcpy(&fptr, &temp, sizeof fptr); fptr("test.conf", &pco

我在问自己,当我没有为fptr分配内存时,为什么这段代码工作得很好。我希望它有一个未定义的行为,因为执行memcpy时没有为fptr或

struct conf *pconf = NULL; 
void (*fptr)(char *, struct conf **);
void *temp = dlsym(dlptr, "config_run_all"); 
memcpy(&fptr, &temp, sizeof fptr); 
fptr("test.conf", &pconf);

您已经为
fptr
分配了内存:

void (*fptr)(char *, struct conf **);`
这将
fptr
声明为指向函数的指针

memcpy()


问题在于从
memcpy()
中省略
&
;然后,当
fptr
未设置为指向任何内容时,您将尝试复制到内存。

您的代码基本上等同于:

struct conf *pconf = NULL; 
void (*fptr)(char *, struct conf **) = (void (*)(char*, struct conf**)) dlsym(dlptr, "config_run_all"); 
fptr("test.conf", &pconf);

没有
temp

,线索就在memcpy调用中

memcpy(&fptr, &temp, sizeof fptr); 

您正在复制到指针的地址,而不是取消引用它。这是在覆盖指针变量本身的内存,而不是它指向的内容(什么都不是)。

我被这个问题弄糊涂了;为什么您说您没有为
fptr
分配内存?这是一个变量;根据定义,它是一个存储位置。这是未定义的行为,只是不是因为你认为它是的原因。如果我没记错的话,空指针被允许大于函数指针,因此您可能没有将正确的位复制到
fptr
@EricLippert中。不幸的是,使用POSIX函数
dlsym
需要使用未根据C标准定义的行为。但是强制转换比
memcpy
好。那么他将
void*
复制到函数指针中的事实呢?我认为这是有问题的,因为这些指针类型不一定大小相同。@FilipeGonçalves:我们在同一时间有相同的想法;请看上面的评论。@EricLippert是的,我刚读过。然后我看到了interjay的评论,这解释了代码背后的基本原理。不过,我还是更喜欢强制转换。@FilipeGonçalves:情况很复杂,因为POSIX 2013取消了指向函数的指针和指向对象的指针具有相同大小的明确保证。据我所知,他们给
dlsym()
函数增加了负担。我有关于它的文档,但我还没有理解它。一些指针:更改编号:XSH/TC1/D5/0017[74][…]章节:2.12.3指针类型删除章节2.12.3:[…]理由:应用的奥斯汀集团缺陷报告:74。参见TC1[as]文件U130的全文