Reputation: 13
I have a file pointer which is valid before calling fread, and NULL after, and I'd really like to know why.
Here is the relevant code:
244 // open the file for reading
245 clo->heap_file = open_file(heap_path, "rb");
443 // allocate memory to read a page from the file
444 file_page = safe_malloc(clo->page_size);
446 // read a page in to memory from the file
447 read_page(file_page, clo);
void *
safe_malloc(size_t size)
{
void * mem_block = NULL;
mem_block = calloc(1, size);
if (mem_block == NULL) {
fprintf(stderr, "ERROR: safe_malloc() failed to allocate memory.\n");
exit(EXIT_FAILURE);
}
return (mem_block);
}
FILE *
open_file(char * file_name, char * file_mode)
{
FILE * fp;
char * err_msg = ((strcmp(file_mode, "rb") == 0)
? "File not found"
: "File could not be created");
fp = fopen(file_name, file_mode);
/* Print an appropriate error message and exit if open failed */
if (fp == NULL) {
fprintf(stderr, "%s: %s\n", err_msg, file_name);
exit(EXIT_FAILURE);
}
return fp;
}
void
read_page(clo_t * clo, void * file_page)
{
fread(file_page, sizeof(size_t), clo->page_size, clo->heap_file);
if (ferror(clo->heap_file)) {
fprintf(stderr, "ERROR: could not read heap file!\n\n");
free(file_page);
destroy_clo(clo);
exit(EXIT_FAILURE);
}
}
GDB trace:
(gdb) p clo->heap_file
$1 = (FILE *) 0x603070
(gdb) s
read_page (clo=0x6032d0, file_page=0x603010) at dbquery.c:331
331 fread(file_page, clo->page_size, 1, clo->heap_file);
(gdb) s
333 if (ferror(clo->heap_file)) {
(gdb) p clo->heap_file
$2 = (FILE *) 0x0
And Valgrind doesn't indicate that I'm doing anything wrong either...
I'd like to think that I'm pretty good at handling return values, making sure pointers are valid, etc, but this one has me stumped.
Upvotes: 1
Views: 1094
Reputation: 53316
You have 2 issues,
Change 447 read_page(file_page, clo);
to 447 read_page(clo, file_page);
as per definition of the function.
Change fread(file_page, sizeof(size_t), clo->page_size, clo->heap_file);
to fread(file_page, 1, clo->page_size, clo->heap_file);
. Do not use sizeof(size_t)
as 2nd parameter to fread
.
Your call will try to read sizeof(size_t) * clo->page_size
bytes which is more than you have allocated for file_page
that is 1 * clo->page_size
.
Upvotes: 2