C buffer memory allocation
I'm quite new to C so please bear with my incompetence. I want to read an whole EXEcutable file into a buffer:
#include <stdlib.h>
FILE *file = fopen(argv[1], "rb");
long lSize;
fseek(file, 0, SEEK_END);
lSize = ftell(file);
fseek(file, 0, SEEK_SET);
char *buffer = (char*) malloc(sizeof(char)*lSize);
fread(buffer, 1, lSize, file);
The file has 6144 bytes (stored correctly in lSize) but the size of my buffer is only 4 bytes, therefore only the MZ signature is stored in the buffer.
Why does malloc only allocate 4 bytes in this case?
Edit: Probably the char buffer is terminated by the first 0 in the MZ header of the PE file. If I set the buffer to a certain value however, the whole file will be stored. If I set the buffer to int (= 4 bytes), the buffer won't be terminated but will be of course larger (vs. char = 1 byte). I just want to copy the file byte for byte with the null bytes as well.
Edit 2: The buffer of course contains everything it should but if I try to write it to a new file with fwrite, it only wrote up to the first \0 (which is 4 bytes). I just got fwrite wrong. Fixed this. Sorry, the probl开发者_运维知识库em wasn't well defined enough.
If lSize
really does equal 6144
then your code will indeed allocate 6144
bytes and then read the entire contents of the file. If you believe that only 4 bytes are being read it is probably because the 5th byte is a zero. Thus when buffer is interpreted as a zero terminated string, it terminates at that point.
You can inspect the rest of your buffer by looking at buffer[4]
, buffer[5]
, etc.
As an aside, you don't need to cast the return from malloc
, and sizeof(char) == 1
by definition. Best practice is to write the malloc
like this:
char *buffer = malloc(lSize);
But that will not change your results.
Why does malloc only allocate 4 bytes in this case?
Because you failed to #include <stdlib.h>
(and cast the return value of malloc()
).
Do not forget to #include <stdlib.h>
so that the compiler knows malloc
returns a value of type void*
(rather than assuming it returns an int
) and takes an argument of size_t
type (rather than asuuming it is an int
)
Also do not cast the return value of malloc
. A value of type void*
can be assigned to an object of pointer (to any type) type. Casting the return value makes the compiler silently convert int
(assumed when <stdlib.h>
was not included) to the type in the cast. Note the compiler would complain without the cast letting you know you had forgotten the include.
The real error is not malloc
allocating the wrong amount (I believe it will allocate the correct amount anyway). The real error is assuming malloc returns an int when it returns a void*. int
and void*
can be passed differently (one in a register, the other on the stack for instance) or they have different representations (two's complement for int
and segmented address for void*
) or any other thing (most probably sizeof (int) != sizeof (void*)
).
how are you checking for the size of buffer, are you doing a sizeof(buffer)
? In that case you are only seeing the size of a pointer to int
which is 4 bytes. You cannot get the size of a buffer out of it's pointer. You must store it separately as you have done (in lSize
).
If malloc()
did not return NULL
then your buffer is fine and the size is correct.
精彩评论