First, a small section of one of your mistakes:
==30352== Invalid write of size 8 ==30352== at 0x401661: HeapMem_map (heapmem.c:84) ==30352== by 0x400E74: map (um.c:109) ==30352== by 0x4010FD: runOpcode (um.c:182) ==30352== by 0x4011A1: UM_run (um.c:209) ==30352== by 0x400A71: main (main.c:10) ==30352== Address 0x4c53b00 is 0 bytes after a block of size 16 alloc'd ==30352== at 0x4A0610C: malloc (vg_replace_malloc.c:195) ==30352== by 0x401425: HeapMem_new (heapmem.c:32) ==30352== by 0x400ABE: UM_new (um.c:31) ==30352== by 0x400A64: main (main.c:8)
Please note that the bottom of this list indicates where the distribution occurred. The top tells you how it was misused. In this case, you will go to the end of the requested allocation of 8 bytes.
You will notice that all overflows in this and the remaining violations exceed their means in exactly the same offset (8 bytes). Further consideration of the reference code shows that it is always the same array. Actually, this is good, since it is very likely that the problem is simply incorrectly calculated, how the data elements are present and reach one or two outside the legal space.
In this case, the element that is violated is represented by a dynamically allocated list of pointers ( heapmem->HeapMem_car[] ). Running on a machine with 64-bit pointers will do each of the 8-byte characters, so you are most likely just one after the other in the last available element of this distribution and in C, which usually always means indicate that you selected N elements, and then got access to array[N] , forgot the limit of N-1 . All of the above access violations seem to be centered around the belief that the indexes in this array are not out of bounds, but valgrind reports that they are. I suggest you skip some assert () element to these access points and break the violation to find out how you got there. Oh wait .. valgrind already has this information for you. Look at this beautiful call stack. Hmmm ...
So why does he even work with these violations? A number of possibilities. If you do not go far beyond the allocated memory - and all addresses are 0 bytes after - (after all, these are pointers, so pray that they are NULL) there is a good chance that you will not overwrite important data and the program seems to work. Until the allocation lands somewhere else and you cross the page boundary. Overload it and kerboom.
Thanks to Daniel Fisher for contributing to the second part of this answer (why this works).
source share