4

I have an application which is loading all dynamically created datamodules into a TList. Application is running under windows XP OS. When closing the application from the application close button the code executes correctly. But when closing the application from the taskbar menu an Invalid pointer operation is raised. The same code behaves different when closing the application in different ways.

the code responsible for destroying the datamodules

  for iPos := 0 to FDatamodules.Count - 1 do //FDataModules is of type TList
    if FDatamodules.Items[iPos] <> nil then 
      TDatamodule(FDatamodules.Items[iPos]).Free;

and the stack

:7c812a6b kernel32.RaiseException + 0x52
System.TObject.FreeInstance
System.ErrorAt(2,$4A7FEFC)
System.Error(reInvalidPtr)
System.TObject.FreeInstance
System._ClassDestroy(???)
Classes.TDataModule.Destroy
System.TObject.Free
RBAFORM.TRBABaseForm.Destroy

LE: It seems that closing the application from the taskbar menu is sending a HALT(0) to the application and the datamodule get freed. On the image bellow :on the left is the stack of the normal close action, on the right the stack of closing application from the taskbar menu.

enter image description here

RBA
  • 12,337
  • 16
  • 79
  • 126
  • 6
    How do you create the datamodules? Create(Nil) should be the correct way here. – LU RD Feb 17 '13 at 11:07
  • @LURD - what I do not understand is why this code is working when closing the application from the application close button, BUT when closing it from taskbar menu is crashing. The same code is executed, but it crashes when closing it from the taskbar menu. – RBA Feb 17 '13 at 13:24
  • 1
    It's probably a David explained, depending of the order when the datamodules are freed. If you manually destroy the datamodules first, it is ok, but the other way is not ok. There could be a race condition which comes first. – LU RD Feb 17 '13 at 13:28
  • 3
    Double free is not always a runtime error. Sometimes you are unlucky and it runs without error. – David Heffernan Feb 17 '13 at 13:59
  • 2
    Jens' will be the most specific answer with the level of information you provided. – Sertac Akyuz Feb 17 '13 at 21:43

1 Answers1

8

This seems to be a double free problem (like LU commented on you question) which means that you are freeing an instance of you data module more then once.

When you create an instance with Create(nil) it's not owned by anyone and you can safely call Free on it. (See also What is the meaning of nil owner in component constructor)

If you create it with Create(Form1) (non nil argument) then it's no longer your responsibility to call Free. It will be automatically freed when Form1 is freed in this example.

To be sure what's going on you should use FastMM in FullDebugMode or a similiar memory debugger. A memory debugger should be able to catch the problem and provide you with more helpful information.

Community
  • 1
  • 1
Jens Mühlenhoff
  • 14,565
  • 6
  • 56
  • 113
  • 2
    If you create a component that is owned, then it is still fine to free it manually. It will notify the owner which removes it from its list of owned components. But if the owner goes down first then, then invalid pointer op is likely. +1 – David Heffernan Feb 17 '13 at 13:21