Reputation: 663
I'm trying to read all bytes from a .raw file and store it in an array, using fread. This is my code:
//open up card file
FILE* file = fopen("card.raw", "r");
if (file == NULL)
{
printf("Unable to open/create file\n");
return 1;
}
//size of file
fseek(file, 0, SEEK_END);
int size = ftell(file);
fseek(file, 0, SEEK_SET);
//buffer array
int buffer[size];
fread(&buffer, 512, size/512, file);
return(0);
I want to read 512 bytes at a time and everything in the file. Now my code gives me Segmanetation Fault
, why is this? I guess it has to do with memeory leak or something similar but I can't figure it out. I also tried to change the mode of the file file
to w
but then all file contents disappear. What am I doing wrong?
Upvotes: 0
Views: 5741
Reputation: 120634
So there are a few issues with your code:
size
and int buffer[size]
: size
is the number of bytes in the file, so creating an integer array of size size
will actually use size * 4
bytes. You mention in the comments that your file is 14.3MB so the buffer
array will be 57.2 MB. If you actually want to read 4 byte integers, then you need to adjust the size of your buffer
array accordingly (divide by 4 and account for remainder - more on this later).ulimit -s
at the command line to see the maximum number of kilobytes on the stack. On my machine this is 8 MB and trying to fread
into a larger array causes a segfault. If you want to read this entire file in to memory, you will need to use the heap (malloc
/free
).size/512
: Integer division throws away the remainder, so this calculation is wrong.buffer
(you are using &buffer
) you want to pass the address of the first element of buffer
which conveniently can be done by just using buffer
(or &buffer[0]
but you rarely see this in reality).Here is a "working" version of your program:
#include <stdio.h>
#include <stdlib.h>
#define BYTES_PER_READ 512
int main(int argc, char *argv[])
{
long size;
size_t number_of_ints;
size_t number_of_elements;
size_t read;
int *buffer;
/* Open up card file */
FILE *file = fopen("card.raw", "r");
if (!file) {
fprintf(stderr, "Unable to open/create file\n");
return 1;
}
/* Size of file */
fseek(file, 0, SEEK_END);
size = ftell(file);
fseek(file, 0, SEEK_SET);
/* 'size' is the number of bytes, not the number of ints,
so we need to adjust accordingly */
number_of_ints = (size % sizeof(int) ? 1 : 0) + (size / sizeof(int));
/* We want to read 512 bytes at a time, and we need to know
how many we need to read to consume the whole file
(this is identical to the calculation above) */
number_of_elements = (size % BYTES_PER_READ ? 1 : 0) +
(size / BYTES_PER_READ);
if (!(buffer = malloc(number_of_ints * sizeof(int)))) {
fprintf(stderr, "Failed to allocate memory\n");
return 1;
}
read = fread(buffer, BYTES_PER_READ, number_of_elements, file);
printf("I read %zu elements of size %d bytes (total bytes read: %zu)\n",
read, BYTES_PER_READ, read * BYTES_PER_READ);
free(buffer);
return 0;
}
If you could describe what your intend to do with the contents of the buffer
array, someone could potentially tell you a better way to go about it (the way you are reading right now is a bit odd...)
Upvotes: 1