2014-03-26 65 views
-1

我在問自己爲什麼這段代碼在我沒有爲fptr分配內存時工作得很好。我期望它有一個未定義的行爲因爲沒有爲fptr分配內存或做memcpy?在不使用malloc分配內存的情況下執行memcpy

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); 
+2

我對這個問題感到困惑;你爲什麼說你沒有爲'fptr'分配內存?這是一個變量;它根據定義是一個存儲位置。 –

+1

這是未定義的行爲,只是不是因爲你認爲它的原因。如果我沒有記錯,void指針可以大於函數指針,因此您可能不會將正確的位複製到'fptr'中。 –

+1

@EricLippert不幸的是,使用POSIX函數'dlsym'要求您使用C標準未定義的行爲。但是,鑄造比「memcpy」更好。 – interjay

回答

3

您已分配的內存爲fptr

void (*fptr)(char *, struct conf **);` 

這聲明fptr作爲函數指針。

memcpy()的從temp值賦值到fptr,使得它使得fptr指向函數temp點。

會有什麼問題會從memcpy()中省略&;那麼當fptr尚未設置爲指向任何內容時,您將嘗試複製到內存。

+0

那麼他將'void *'複製到函數指針中怎麼樣?我認爲這是有問題的,因爲這些指針類型不一定是相同的大小。 –

+0

@FilipeGonçalves:我們在同一時間有同樣的想法;見上面的評論。 –

+0

@EricLippert是的,我剛剛讀過它。然後我看到了interjay的評論,這種解釋代碼背後的基本原理。但是,我仍然喜歡施放。 –

2

您的代碼基本上等同於:

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

不用其他temp

2

線索在memcpy調用中。

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

您正在複製到指針的地址,而不是取消引用它。這覆蓋了指針變量本身的內存,而不是它指向的內容(這不算什麼)。

+1

fptr = temp本來可以做同樣的工作:) – user3329849

相關問題