0

In C the fread() has a parameter of a void* which will be assigned the value of the next chunk of bytes being read from the file. My understanding is that a void* is used so that several data types can be given to the function. However when I try to use this type of parameter in my own function it seems that assigning a value to a void* is not allowed.

For example:

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

This gives an error saying that void is not assignable. If this is the case then how does it work in the fread()?

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • possible duplicate of [Assign values to a dereferenced void pointer](http://stackoverflow.com/questions/7081288/assign-values-to-a-dereferenced-void-pointer) – Barmar Jan 02 '15 at 00:39
  • @Barmar I saw this, I did not see a satisfactory answer and no explanation was given to why it can be used in fread() and not other functions. –  Jan 02 '15 at 00:41
  • Those functions contain code similar to the answer there. They cast the pointer to an appropriate type before dereferencing it. – Barmar Jan 02 '15 at 00:45

4 Answers4

2

The implementation of fread is none of your business, but presumably it will create a char-like pointer from your void pointer and assume that the pointer you provided was created from a valid, non-null object pointer. For example:

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
    // ...
}

This makes sense because you can treat any object as an array of characters, but passing a void * argument is simpler since the conversions from object to void pointers are implicit and don't need explicit casts.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • `fread` probably uses `memcpy` instead of messing with individual chars,and so doesn't need that cast. – Jasen Jan 02 '15 at 01:27
  • it's probably written in assembler :) but implementations written in portable C are not unlike your code, converting the void* into a writable pointer type. – Jasen Jan 02 '15 at 01:34
0

Maybe you need this: int* ptr = malloc(sizeof(int));, or recast it by *(int*)(ptr) = n.

Jake0x32
  • 1,402
  • 2
  • 11
  • 18
  • I want it to be able to handle any of the raw data types not just 1 –  Jan 02 '15 at 00:44
0

void by definition is not assignable. You might do it this way:

*(int*)ptr = n;

But basically you (probably) make mistake in a way you allocate memory. i would recommend this:

int* ptr = malloc(sizeof(int));
int n = 5;
*ptr = n;
user253751
  • 57,427
  • 7
  • 48
  • 90
0

fread() uses something like memcpy() to copy the data from a buffer that was filled using read() or _read() or READ() or something platform specific like that.

Jasen
  • 11,837
  • 2
  • 30
  • 48