In most cases it happens due to freeing something, that should be freed elsewhere, when program terminates. If you don't do it, then it's worst and most tricky case, programmer could possibly encounter - heap corruption. Heap corruption is tricky, just because AV happens not when heap is actually being corrupted, but much later - at any arbitrary moment, when this object is being used. Also heap corruption - is floating bug. It may stay unnoticed on your computer, but appear on another. For example when I develop my programs, 32bit version may work correctly, but 64bit may throw "Invalid pointer operation" faults. Worst case of heap corruption, I've ever encountered - is when call to some GDI API, like GetWindowRect, in one part of the program was causing AV in hal.dll in completely different part of program, that wasn't directly connected with this one. Some memory managers, like FastMM, can track heap corruptions, if they happen with your heap - not heaps of some other dlls. In some cases heap corruption isn't obvious and can be tracked only via using asm debugging, cuz sometimes heap corruptions happen due to so called "compiler magic". But in most cases best method - is to notice recent changes in code, that caused this error, and try revert them. And of course - to write safe code.
P.S. Do you use dlls? At least in Delphi passing strings to dll without using ShareMem causes heap corruption.