10
votes

I can't seem to figure this one out. My program compiles and runs successfully, but during debugging only it pops up a message box saying "Invalid Pointer Operation" when shutting the program down. I have painstakingly checked all the FormCloseQuery and FormDestory events for any syntax or logical error. I found none and they execute as expected without any error.

enter image description here

When I do tell the compiler to break at Invalid Pointer Operation error, it doesn't do anything but hangs up the program. At which point, I had to terminate or kill the process.

How do you figure this one out?

Thanks in advance,

4
Enable Debug DCUs and step through the shutdown until you can find what triggers this error. Are you running with FastMM in Full Debug mode? - David Heffernan
@DavidHeffernan, :) I remember we had a conversation about FastMM. Unfortunately, I have not used FastMM since I test ran it while back. I will enable DCU and see what happens. - ThN
@DavidHeffernan, after the break with dcu enabled, debugger stopped in System.pas file. Bit confusing but I thinking its because one of Mason wheeler's reason. I guess now I have to put FastMM back in. - ThN
Set some stack tracer and perhaps turn one "use debug DCUs" It looks that you have some stray pointer that youtry to free two times. stackoverflow.com/questions/3631987 stackoverflow.com/questions/12505251 stackoverflow.com/questions/2237028 - Arioch 'The
If you "found none," then you need to look harder, because obviously there is a problem in your program. - Rob Kennedy

4 Answers

30
votes

An Invalid Pointer exception is thrown by the memory manager when it tries to free invalid memory. There are three ways this can happen.

The most common is because you're trying to free an object that you've already freed. If you turn on FastMM's FullDebugMode, it will detect this and point you directly to the problem. (But make sure to build a map file so it will have the information it needs to create useful stack traces from.)

The second way is if you're trying to free memory that was allocated somewhere other than the memory manager. I've seen this a few times when passing a string from a Delphi EXE to a Delphi DLL that wasn't using the shared memory manager feature.

And the third way involves messing around with pointers directly and probably doesn't apply to you. If you try to FreeMem or Dispose a bad pointer that doesn't refer to an actual block of memory allocated by FastMM, you'll get this error.

It's most likely the first one. Use FullDebugMode and you'll find the source of the problem easily.

9
votes

Invalid pointer operations occur when you tell the Delphi memory manager to release memory that doesn't belong to it. There are three ways that might happen:

  • Freeing a pointer or object that has already been freed.
  • Using FreeMem to free something that was allocated by some other memory manager (such as GlobalAlloc or CoTaskMemAlloc).
  • Freeing an uninitialized pointer. (This is distinct from freeing a null pointer, which is completely safe.)

Somewhere in your program, you are doing one of those things. The debugger has detected the exception thrown by the memory manager, so do some debugging. From the stack trace, you should be able to see which variable you're trying to free. Check the rest of your program for other ways that variable is used.

Tools like MadExcept and Eureka Log can help you find double-free errors. They can keep track of where the pointer in question got allocated and where it was freed the first time, and that is sometimes enough information to figure out your mistake and stop freeing things multiple times.

1
votes

A 4th reason an invalid pointer operation can occur. I had two pointers that where array[0..1000] of real and a third pointer that was an array[1..200] of real. All 3 pointers where initialized with for i := 0 to 1000 do begin ptr1^[i]:=0;ptr2^[i]:=0;ptr3^[i]:=0; end; While this poor programing did not bother Pascal in Delphi a call to Dispose any of the 3 pointers resulted in an Invalid Pointer Operation. The fix was simply to initialize the 3rd pointer correctly.

0
votes

I have been caught out by this type of "indicated error" during Delphi debugging.

Check if you have any watched variables with "Allow Function Calls" enabled or watches that try to show other variables in the same unit (or global) that might be uninitialised. When stopping on a breakpoint this can cause Delphi's debugger to attempt to display the value via a function call that accesses an uninitialised Pointer or variable. The actual variable that causes the AV my not even be on your watch list.