1
typedef uint8_t BYTE;

int main(void)
{
    FILE* memcard = fopen("card.raw", "r");

    if (memcard == NULL)
    {
        printf("something went wrong and file could not be opened");
        return 1;
    }

    int* block = malloc(sizeof(BYTE) * 512);

    while(!feof(memcard))
    {
        fread(&block, sizeof(block), 1, memcard);

        if (block[0] == 0xff && block[1] == 0xd8 && block[2]== 0xff && (block[3]== 0xe0 || block[3] == 0xe1))
        {
            printf("found one jpg!\n");
        }
    }

    fclose(memcard);
}
1
  • Please run your program with valgrind and paste the results here. – Luke Van In Aug 13 '14 at 11:17
1

The SEGFAULT is because the code is not passing the correct pointer value to fread:

  fread(&block, sizeof(block), 1, memcard);

Here block is already a pointer. So what this line of code is doing, is going to that pointer, fetching the first value in the block array, and then using that as the address of where you want to write your data to.

Since block is already a pointer it can just be passed to fread - the "address of" operator (&) is not required. E.g:

  fread(block, sizeof(block), 1, memcard);

On the other hand, if block is a local stack variable, then the "address of" operator is required, e.g:

BYTE block[512];

while(!feof(memcard))
{
    fread(&block, sizeof(block), 1, memcard);
    ...
}

Note that since block is not a pointer, you need to get a pointer to it using the &.


To pre-empt your next question.

There are some other errors (not related to the crash) in the code where it reads the incorrect number of bytes. The second example above shows the correct usage. The original code is using sizeof incorrectly:

sizeof(block)

Since block is a pointer, this will return the number of bytes used by the pointer itself, not the value it's pointing to. Pointers are usually 4 bytes in size. So by passing this value to fread, it will only read 4 bytes.

This can be confusing in C because the pointer is just a single number which refers to the start of an array in memory, it does not contain information about how much memory is allocated at that location. This is why we need to pass both the pointer block, and the size of the memory to read. The correct usage would be:

  fread(block, sizeof(BYTE), 512, memcard);

Again, if block were a local stack variable, then sizeof would return the correct size, because the size of stack variables is known at runtime.


A great way to debug SEGFAULT errors is to run your program with valgrind. To do this, just type valgrind space, followed by the usual command to run the program. When the program crashes, valgrind will display the exact line number where the crash occurred.

1
  • 1
    Thanks mate! looks like i still need to do some reading about pointers, just to add for future reference, block should be a pointer to a BYTE instead of an int BYTE* block = malloc(sizeof(BYTE) * 512) – Oussama Aug 13 '14 at 18:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .