1

I redesigned my code but now I get the following error message: Error in ./recover: double free or corruption (top)

Can you help what's wrong?

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>


typedef uint8_t BYTE;

int main(int argc, char* argv[])
{

// ensure proper usage
if (argc != 1)
{
    printf("Cannot accept command-line arguments\n");
    return 1;
}

// open raw.c file
FILE* cardptr = fopen("card.raw", "r");

// make sure file can be opened
if(cardptr == NULL)
{
    printf("Could not open file\n");
    return 2;
}

int n = 0;
BYTE block[512];
char jpgname[10];

FILE* imgptr = NULL;

while (fread(block, sizeof(block), 1, cardptr) == 1)
{

    if(block[0] == 0xff && block[1] == 0xd8 && block[2] == 0xff &&   (block[3] == 0xe0 || block[3] == 0xe1))
    {  
        if(imgptr != NULL)
        {          
            fclose(imgptr);
        }
        else
        {
            sprintf(jpgname, "%03d.jpg", n);
            imgptr = fopen(jpgname, "a");  
            fwrite(block, sizeof(block), 1, imgptr);
            n++;
        }
     }

     else if(imgptr != NULL)
     {
        fwrite(block, sizeof(block), 1, imgptr);
     } 


}

if(imgptr != NULL)
{
    fclose(imgptr);
}

fclose(cardptr);    
return 0;

}

1 Answer 1

2

TL;DR: try changing:

    if(imgptr != NULL)
    {          
        fclose(imgptr);
    }
    else
    {
        sprintf(jpgname, "%03d.jpg", n);
        imgptr = fopen(jpgname, "a");  
        fwrite(block, sizeof(block), 1, imgptr);
        n++;
    }

to:

    if(imgptr != NULL)
    {          
        fclose(imgptr);
    }
    sprintf(jpgname, "%03d.jpg", n);
    imgptr = fopen(jpgname, "a");  
    fwrite(block, sizeof(block), 1, imgptr);
    n++;

Rationale:

Someone asked about this error on stackoverflow and here's an excerpt from one answer:

Double free means free(x) was called twice in a row with the same value of x. Somewhere in your code free(x) is called and then most likely in another piece of code free(x) is called again. https://stackoverflow.com/questions/12548868/why-am-i-getting-this-memory-access-error-double-free-or-corruption

With that in mind, it seems a likely guess that somehow your program is trying to execute fclose() more than once on the same file.

Looking through your code, I really enjoyed seeing the ways that you implemented this better than I did, but now that I think I understand your approach, I think you might be tripping up in your if/else block.

If I understand this correctly, you are checking whether imgptr is null.

    if(imgptr != NULL) 

If it is null, you execute the else code, where you generate a name, open a file, etc...

        sprintf(jpgname, "%03d.jpg", n);
        imgptr = fopen(jpgname, "a");  
        fwrite(block, sizeof(block), 1, imgptr);
        n++;

If imgptr is not null, you are executing the if block, where you close the file.

        fclose(imgptr);

Since imgptr is initialized to NULL, the first time a .jpg header is found, the else block will be executed.

On finding the second .jpg header, I believe imgptr will no longer be NULL, so the if block will execute, but if I'm not mistaken, the else block of code will not be executed, the file name won't be updated, no new file will be opened, etc...

My guess is that the program will go on, probably issuing errors for every subsequent fwrite() call, until it hits the third header block, where it will again see that imgptr is not NULL and will try execute fclose(imgptr); again.

Take this with a grain of salt, as I'm new to this, but I hope it helps.


If this answers your question please accept it by clicking the gray check-mark to the left, so that it becomes green. You can also vote it up by pressing the up arrow above the check-mark.

You must log in to answer this question.

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