2

I'm trying to read a binary file that has blocks starting with an identifier (like a 3DS file). I loop through the file and using a switch the program determines what identifier a block has and then reads the data into the file struct. Sometimes I need to use malloc to allocate memory for dynamic sized data. While reading, the switch often goes through the same case wherin memory is allocated, but at a specific point in the file it crashes on that same malloc. The file that I want to read is about 1MB. But when I try the program with another file of about 10kB and the same structure, it reads it succesfully.

What could be causing this problem?


The error code that I get when debugging is:

Heap corruption detected at 0441F080
HEAP[prog.exe]: HEAP: Free Heap block 441f078 modified at 441f088 after it was freed

Also when I execute it in debug mode, for some reason I can read more data from the file. The program lives longer before it crashes.


Here is the code piece where it crashes:

switch (id) {
    case 0x62:
    case 0x63:
    // ...
        {
            char n_vertices = id - 0x60 + 1;// just how I calculate the n_vertices from the block ID
            fread(&mem.blocks[i].data.attr_6n.height, 2, 1, f);
            mem.blocks[i].data.attr_6n.vertices = malloc(2 * n_vertices);// crash
            for (short k = 0; k < n_vertices; k++) {
                fread(&mem.blocks[i].data.attr_6n.vertices[k], 2, 1, f);// read shorts
            }
        }
        break;
    // ...
}
Midas
  • 7,012
  • 5
  • 34
  • 52

3 Answers3

9

You probably have a corrupt heap. This could be caused by invalid deallocations (deallocating unowned or already free memory), or by some random chunk of code writing outside its memory area into a place that happens to hold the heap bookeeping data structures. This most likely will be a piece of code that has nothing whatsoever to do with that dynamically allocated memory.

Tracking down bugs like this is a real bear. They tend to appear long after the offending code has executed, and they have an annoying tendency to turn into heisenbugs (bugs that move or go away when you attempt to debug them).

My suggestion for approaching debugging would be to try to comment out portions of your code and see what causes the problem to go away. That isn't foolproof, as you could just end up moving the out-of-bounds write to somewhere else.

Looking over the code you just posted, one thing I would highly suggest you do is verify that your malloc specified enough memory to hold all the data you are attempting to load into it. It looks to me like you are assuming 2 bytes for each vertex. That seems a bit suspicious to me. I don't know your code, but 4 or 8 would be much more common element sizes to see there. Regardless, industry practice is to use sizeof() on the target type to help ensure you have it right.

Another option, if that debugger message of yours can show you where it is happening, would be to put a debugger watch point there (or write some watching code...or manually dump and inspect the area) when stepping in the debugger to try to figure out which is the offending line of code.

Good luck. I hate these bugs.

T.E.D.
  • 44,016
  • 10
  • 73
  • 134
  • In my program I never freed any allocated memory, and I'm sure I never wrote data outside the bounds of the allocated space because I know the exact file specification. – Midas Apr 26 '11 at 22:38
  • 1
    @Midas - Well, the latter is tough to know for sure, particularly in such a massively unsafe language. C just gives you too many tools for shooting yourself in the foot. Clearly **something** is wrong. – T.E.D. Apr 26 '11 at 22:44
  • 1
    Knowing the exact file specification doesn't do anything to prevent mistakes, do you have access to a tool like valgrind to verify your code with? I strongly suggest using such a tool for C code whenever possible. – asm Apr 26 '11 at 22:56
  • @Midas - To clarify a bit, it could be *any* line in your program causing this problem, if it for some reason writes to a bad area. For example, I've seen simple array off-by-one indexing errors in C cause entire other machines to crash before (the garbage past the end of the array was passed over the network to the other machine. When that machine tried to use the garbage as an index into one of its arrays...*boom!*) – T.E.D. Apr 26 '11 at 22:56
  • OK, but it's still strange that it doesn't crash at the same moment in debug mode. – Midas Apr 26 '11 at 22:59
  • Oh ok, I'll read that tomorrow. I'm gonna sleep now... Thanks! – Midas Apr 26 '11 at 23:03
3

Most likely the heap gets corrupted somehow, malloc is crashing e.g. trying to traverse a corrupted linked list of free blocks (or a similar structure, I'm not exactly sure what is used in modern heap allocators these days).

Make sure your code is not writing past the end of an allocated block.

Code Painters
  • 7,175
  • 2
  • 31
  • 47
0

You need to run this in a memory debugger like valgrind. Since it looks like you're on windows, see the following: Is there a good Valgrind substitute for Windows?

Community
  • 1
  • 1
BMitch
  • 231,797
  • 42
  • 475
  • 450