2015-01-02 3 views
0

В C fread() имеет параметр void *, которому будет присвоено значение следующего фрагмента байтов, считанных из файла. Мое понимание заключается в том, что void * используется так, что функции могут быть переданы нескольким типам данных. Однако, когда я пытаюсь использовать этот тип параметра в своей собственной функции, кажется, что присвоение значения void * недопустимо.Назначение значений для void *

Например:

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

Это дает ошибку о том, что пустота не может быть назначен. Если это так, то как это работает в fread()?

+0

Возможный дубликат [Присвоение значений указателю недействительности void] (http://stackoverflow.com/questions/7081288/assign-values-to-a-dereferenced-void-pointer) – Barmar

+0

@Barmar Я видел это, я не нашел удовлетворительного ответа и не было объяснено, почему его можно использовать в fread(), а не в других функциях. – JDOdle

+0

Эти функции содержат код, похожий на ответ. Перед разыменованием они накладывают указатель на соответствующий тип. – Barmar

ответ

3

Реализация fread не ваше дело, но предположительно это создаст char -кака указателя с вашего пустым указателя и предположит, что указатель вы предоставили был создан из действительного, непустого указателя на объекте. Например:

You:

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() или что-то конкретной платформы, как это.

Смежные вопросы