2015-01-02 155 views
0

在C中,fread()具有void *的參數,該參數將被分配從文件讀取的下一個字節塊的值。我的理解是使用void *,以便可以爲該函數提供多種數據類型。但是,當我嘗試在我自己的函數中使用這種類型的參數時,似乎將值賦給void *是不允許的。將值分配給void *

例如:

void* ptr = malloc(sizeof(int)); 
int n = 5; 
*ptr = n; //Error here 

這給出了一個錯誤說無效不可分配。如果是這種情況,那麼在fread()中它是如何工作的?

+0

可能的重複[賦值給解除引用的空指針](http://stackoverflow.com/questions/7081288/assign-values-to-a-dereferenced-void-pointer) – Barmar

+0

@Barmar我看到這個,我沒有看到令人滿意的答案,也沒有解釋爲什麼它可以在fread()中使用,而不是其他函數。 – JDOdle

+0

這些函數包含與那裏的答案類似的代碼。他們在解除引用前將指針轉換爲適當的類型。 – Barmar

回答

3

fread實現是關你的事,但據推測它會從你的空指針創建char般的指針,並假定您提供的指針從一個有效的,非空的對象指針創建。例如:

您:

int data[10]; 

fread(data, sizeof(int), 10, fp); 

FREAD:

size_t fread(void * ptr, size_t sz, size_t nmemb, FILE * fp) 
{ 
    char * dst = ptr; 
    // read data into *dst in chunks of sz bytes 
    // ... 
} 

這是有道理的,因爲你可以把任何對象作爲字符數組,而是傳遞一個void *說法是因爲從對象到void指針的轉換是隱含的,並且不需要顯式轉換。

+0

'fread'可能使用'memcpy'而不是與各個字符混淆,因此不需要這種轉換。 – Jasen

+0

@Jasen但是'memcpy'如何工作? ;) – Quentin

+0

它可能是用匯編寫成的:)但用可移植C編寫的實現與您的代碼無異,將void *轉換爲可寫指針類型。 – Jasen

0

也許你需要這個:int* ptr = malloc(sizeof(int));,或者用*(int*)(ptr) = n重鑄它。

+0

我希望它能夠處理任何原始數據類型,而不僅僅是1 – JDOdle

0

無效的定義是不可分配的。 你可能會做這種方式:

*(int*)ptr = n; 

但基本上你(可能)讓你分配內存的方式錯誤。我會推薦這:

int* ptr = malloc(sizeof(int)); 
int n = 5; 
*ptr = n; 
0

fread()使用類似於memcpy()將數據從使用read()_read()READ()或特定類似的東西平臺填補了緩衝區拷貝。