0

Whenever I want to read or write into a binary file using C, I do use the fread() and fwrite() functions. They need as a parameter the bytes of the datum that is being read or written so I use the sizeof() function. Now the question is:

The books says that I should declare a function like this:

fread(&variable,sizeof(TYPE_OF_VAR),quantity,file);

I've use the following statement which works most of the time but not always:

fread(&variable,sizeof(VARIABLE),quantity,file);  

Why does it works sometimes but sometimes it doesn't?
Does it depends on the type of the variable (int, char, etc)?
Does it depends on the quantity of the datum that I use?

Lucio
  • 4,753
  • 3
  • 48
  • 77
  • Could you please post an example of when this doesn't work, including the source code? – Paul Keister Aug 05 '12 at 22:36
  • 1
    It works when the identifier (the variable) is for an object; it doesn't work when the identifier is for a pointer to object. – pmg Aug 05 '12 at 22:37
  • 1
    `sizeof` applied to a type, in parentheses, gives the size of the type. Applied to an expression, without parentheses, it gives the size of the type of the expression. – Kerrek SB Aug 05 '12 at 22:46

3 Answers3

2

The thing to keep in mind is that sizeof is based on what the compiler knows about the type at compile time (ignoring VLA's for now). If you give it a variable, it will use the type of that variable.

So, the only time I can think of where it wouldn't work as you expect is with pointers.

basically what it boils down to is this:

int x[5];
int *y = &x[0];
int *p = malloc(sizeof(int) * 5);
sizeof(x); // == sizeof(int) * 5
sizeof(y); // == sizeof(int *)
sizeof(p); // == sizeof(int *)

This gets tricky when dealing with functions because arrays decay to pointers when passed to a function. Also note that all 3 of these are exactly equivalent:

int func(int *p);
int func(int p[5]);
int func(int p[]);

in all 3, p is a pointer, not an array.

pmg
  • 106,608
  • 13
  • 126
  • 198
Evan Teran
  • 87,561
  • 32
  • 179
  • 238
1

See this Stack Overflow question for a discussion of heap vs. stack: What and where are the stack and heap.

sizeof() on heap elements, like pointers, will return the size of the pointer, not the number of elements that the pointer can store.

However, sizeof() on stack elements: arrays or const char * will return the length of the array or string.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LENGTH 100

int main(int argc, char *argv[])
{
    char *a = NULL;
    char b[10] = "abcdefghi";

    printf("sizeof(b): %zu\n", sizeof(b));

    a = malloc(LENGTH + 1);
    if (a) {
        *(a + LENGTH) = '\0';
        memset(a, ' ', LENGTH);
        fprintf(stdout, "a (before memcpy):\t[%s]\n", a);
        printf("sizeof(a), before: %zu\n", sizeof(a));
        memcpy(a, b, sizeof(b) - 1);
        fprintf(stdout, "a (after memcpy):\t[%s]\n", a);
        printf("sizeof(a), after: %zu\n", sizeof(a));
        free(a);
    }

    return EXIT_SUCCESS;
}

To compile:

$ gcc -Wall sizeofTest.c -o sizeofTest

Output:

$ ./sizeofTest
sizeof(b): 10
a (before memcpy):     [                                                                                                    ]
sizeof(a), before: 8
a (after memcpy):      [abcdefghi                                                                                           ]
sizeof(a), after: 8

On my platform, a char * points to a memory address that takes up eight bytes.

Community
  • 1
  • 1
Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345
0

It will always work.

int main()
{
    char a[10];
    int b[10];
    printf("%d %d %d %d %d %d",sizeof(char),sizeof(int), sizeof(a),sizeof(b), sizeof(a[0]), sizeof(b[0]) );
}

Try the above code. You should see (depending on compiler, mine has char as 1byte and integer as 4 bytes) 1,4,10,40,1,4

It is not different for fread or fwrite or wherever you use it.

Lucio
  • 4,753
  • 3
  • 48
  • 77
av501
  • 6,645
  • 2
  • 23
  • 34