views:

339

answers:

2

If I declare

PSomeStruct = ^TSomeStruct;
TSomeStruct = record 
  s1 : string;
end;

and I run the following code:

var
  p: PSomeStruct;
begin
  new(p);
  p^.s1:= 'something bla bla bla';
  dispose(p);

the FastMM 4 memory manager reports that there was a memory leak (type: string, data dump: "something bla bla bla"). However, if I do set the s1 string to empty before calling dispose it's OK.

The second way I found is to change from record type to class, then instead of new I'm creating the instance, and instead of dispose I'm calling instance.Free(). It works without manually cleaning the strings.

Is there a way to make Delphi automatically clean my strings when I call dispose?

+1  A: 

You are already doing the correct thing. If FastMM says that string has leaked, then FastMM is wrong, or it's reporting a different string from the one you think it is. The Dispose procedure releases strings from records.

In this particular case, there shouldn't have been any memory allocated for that string anyway. It's a string literal, so I'd expect the compiler to assign that literal; its reference count should be -1 and FastMM never should have seen it.

Rob Kennedy
Well, I cheated a bit to make my idea clear. In fact the string is being loaded from JvSimpleXML, however I'm sure it's the same one that is reported, as I checked it - setting all the string fields in the record empty before "disposing" it makes the memory leak report disappear...
migajek
D7: I have had some experiences of FastMM squawking about similar situations--stuff that should have been cleaned up by record finalization but was being reported as a leak. It seems odd that FastMM could have a bug that only applies to this type of thing, I'm more inclined to suspect a compiler bug as the common element has always been something that should have been cleaned up by record finalization.
Loren Pechtel
Well, turn on "debug DCUs" and step through the `Dispose` call. There should be a call to `_FinalizeArray`, and that should call `_LStrClr`. If it's a compiler bug, then it must be in generating the TTypeInfo data for the record, and if that's wrong, then the `New` code would also be wrong. You'd be in danger of having uninitialized string field.
Rob Kennedy
+1  A: 

Is FastMM the first unit used in your .dpr? Otherwise it could be finalized too early, reporting false memoryleaks.

And does this simplified codesample also generate the same memoryleak as when you use your JvSimpleXML? When it's not, there is probably more going on then you suspect.

In my opinion: when FastMM reports a memory leak, there is a memoryleak.

The_Fox
yep, it's first one. it has noting to do with JvSimpleXML, if I assign literally ANY string (like the one from TEdit.Text) it's also leaking a memory :/
migajek