Just wondering what is the soundest way to allocate memory and fread()
array data from a file in C.
First, an explanation:
int32_t longBuffer;
Now, when freading in the longBuffer, the code could go as:
fread(&longBuffer, sizeof(longBuffer), 1, fd); //version 1
fread(&longBuffer, sizeof(int32_t), 1, fd); //version 2
Among the two, I would say that version 1 is more bug-safe, since if the type of longBuffer
changes (let's say to int16_t
), one does not have to worry about forgetting to update the fread()
's sizeof()
with the new type.
Now, for an array of data, the code could be written as:
//listing 1
int8_t *charpBuffer=NULL; //line 1
charpBuffer = calloc(len, sizeof(int8_t)); //line 2
fread(charpBuffer, sizeof(int8_t), len, fd); //line 3
However, this exhibits the problem exposed in the first example: one has to worry about not forgetting to synchronize the sizeof(<type>)
instructions when changing the type of charpBuffer
(let's say, from int8_t*
to int16_t*
).
So, one may attempt to write:
fread(charpBuffer, sizeof(charpBuffer[0]), len, fd); //line 3a
as a more bug-safe version. This should work since, after the allocation on line 2, writing charpBuffer[0]
is perfectly valid.
Also, one could write:
fread(charpBuffer, sizeof(*charpBuffer), len, fd); //line 3b
However, trying to do the same for memory allocation, such as:
charpBuffer = calloc(len, sizeof(charpBuffer[0])); //line 2a
while better in syntax, exhibits undefined behaviour because, at this stage, writing charpBuffer[0]
results into dereferencing a NULL pointer. Also, writing:
charpBuffer = calloc(len, sizeof(*charpBuffer)); //line 2b
exhibits the same problem.
So, now the questions:
Are the lines of code "line 2b" and "line 3b" correct (ignore the undefined behaviour for this question) or there are some tricks that I miss w.r.t. their "wiser" counterparts such as "line 2a/3a" and "line 2/3"?
What would be the most bug-safe way to write the "listing 1" code, but avoiding any form of undefined behaviour?
EDITS (in order to clarify some aspects):
The discussion took wrong direction. The question of compile time vs run time is one thing (and I would like to have a standard guarantee for this one, too, but it is not the topic). And the question of undefined behaviour for sizeof(NULL dereferencing) is another. Even if at compile time, I am not convinced that this is guaranteed by the standard to not result in UB. Does the standard provide any guarantees?