0

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?

12
  • Were you able to determine if size got the correct value or not? Commented Oct 14, 2014 at 20:50
  • This code will not be reliable. size/512 will be 2 for a file of size 1250 bytes which means you won't read all of the data. You're not checking the return value of fread for errors/short reads. Commented Oct 14, 2014 at 20:52
  • not sure, but I would suspect the array buffer size. At compile time how will it know the size unless it gets from the file? Maybe define buffer to be big enough, say 512 bytes and see if it works. Commented Oct 14, 2014 at 20:55
  • @GauravSinha I don't think setting size to 512 will work since the file is 14.3 MB big. Commented Oct 14, 2014 at 21:03
  • @SeanBright could That be the cause of the segmentation fault? Commented Oct 14, 2014 at 21:07

1 Answer 1

1

So there are a few issues with your code:

  1. 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).
  2. Stack size: The stack is limited on most systems. If you are writing/running this on Linux, try typing 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).
  3. size/512: Integer division throws away the remainder, so this calculation is wrong.
  4. Typos/Other: You don't want to pass the address of 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...)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.