0

I wanted to try using malloc and a BUFFER structure of 512BYTES for this exercise with the intention of creating a file if the 4 signatures of a JPG are detected and fwriting the struct of 512B into the new file, fwriting the struct into a preexisting file if the 4 signatures of a JPG are not detected, or simply freeing the struct if a file does not exist. However, I just get 50 corrupted or grey images based on whether I use if (access( title, F_OK ) != -1) or if(outptr != NULL) (not used in my code at the moment) for my file existence checking, but no matter what no correct images. What am I doing wrong? Also, just a question regarding malloc and free. Everytime I free buf, I have to do buf = malloc(sizeof(BUFFER)) again which is why it is at the bottom of my loop else I get a double free error. Is it because once I free buf, both the allocated space of 512 BYTES and the 512 previously stored bytes are discarded meaning buf is back to pointing at nothing? What happens if I do not malloc again and I fread with buf? Where do the 512 read bytes go since I did not encounter a segmentation fault error but rather a double free error.

[code hidden]

  • You wouldn't have to worry about freeng the memory if you just declare a variable normally without malloc. also why does the buffer have to be a struct? Why not an array of 512 bytes? – Evan Jun 8 '16 at 20:32
  • Yeah I realized I could've just made an array of 512 bytes but I wanted to try out using both a struct and malloc for this exercise – alo129 Jun 8 '16 at 22:22
1

First, the problem with the code lies in this line:

fwrite(&buf, sizeof(BUFFER), 1, outptr);

Adding the & is causing the problem. If you remove it, it will work. If you look at the man page for fwrite, you will see that the first parameter is supposed to be a pointer, not the contents of the memory pointed at, which is what the & triggers. (It's a little confusing. I often mess up with pointers myself because of stuff like this.)

Then, there's malloc and free. Understand that free() will release the memory pointed to by it's argument, but doesn't change the address stored in the argument. That means that when you free the memory, that memory is no longer owned or legally available to the program. So, when you want to use buf again, you have to call malloc() again to allocate new memory and to store that memory's address in buf. (It may or may not be the same physical memory and address.) A call to free() does not reset or reinitialize the contents of memory previously malloc'd. It simply releases it.

The double free or corruption is almost always a double free. This happens when you try to call free() on the same argument a second time without having re-malloc'd memory to that argument pointer. I'll leave it to you to trace your own logic and figure out why that is happening.

While your general concept of malloc'ing and freeing buf is valid, it isn't really necessary and is inefficient. It isn't that you are mallocing and freeing the memory, it's that you are trying to do it for every block read. Instead, you could malloc the memory for the buffer just once, before the while loop starts, and free it once after the while loop ends.

| improve this answer | |
  • Thank you so much!! I can't believe I missed the &buf despite staring at this for so long. I just tried what you suggested in your last paragraph and it works perfectly. I thought I had to free and malloc per loop run because if I didn't, the 512 bytes of memory would have been full due to the previous fread leaving no memory to store the 512 bytes from my current fread. Now that I have your explanation on both malloc and free and removed both from within my loop, does fread simply overwrite what was previously in the 512b of mem with the next 512b it reads or is it something else? – alo129 Jun 9 '16 at 0:21
  • Yes, the buffer will behave like any other variable. If you write something new to it, the old content will be overwritten, at least to the extent of the new write. For example, if you have a 512 byte buffer, write 512 bytes to it, and then execute another write, but only 100 bytes, then the first 100 bytes would be the new data, but the remaining 412 bytes would still contain the old data. Similar effect if you were to write to buf+412, which would leave the first 412 (0 thru 411) intact and then start writing at 412 bytes into the buffer. – Cliff B Jun 9 '16 at 0:29
  • Wow thank you so much for the quick and easy to understand explanation! – alo129 Jun 9 '16 at 1:09

You must log in to answer this question.

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