2010-01-18 24 views
2

我想在Delphi中運行一個老的midi組件,它的大部分工作,但如果我嘗試加載一個行中的2個文件,它崩潰。getmem內存泄漏,德爾福

一些研究讓我安裝了EurekaLog,它指向code.yay中的內存泄漏!

我對內存指針的東西不太好,但是這段代碼被Eureka強調在這裏讓我思考,也許有一個內存沒有被釋放的錯誤?

我試着在它的末尾添加FreeMem,但它不起作用?

function TMidifile.ReadString(F: integer): string; 
var 
    s: PChar; 
    i: integer; 
begin 
    GetMem(s, F + 1); 
    s[F] := chr(0); 
    for i := 0 to F - 1 do 
    begin 
    s[i] := Chr(chunkIndex^); 
    inc(chunkIndex); 
    end; 
    result := string(s); 
end; 
+0

首先,您打電話給FreeMem後,「它不起作用」是什麼意思?其次,你使用的是什麼版本的Delphi? –

回答

2

您不能將類型轉換爲AnsiString,因爲它們是引用計數。

難道這不容易嗎?

function TMidifile.ReadString(F: integer): string; 
var i: integer; 
begin 
    SetLength(Result, F); 
    for i := 1 to F do 
    begin 
    Result[i] := Chr(chunkIndex^); 
    inc(chunkIndex); 
    end; 
end; 
+0

這似乎解決了這種情況!我沒有得到任何泄漏內存的警告:) 感謝您的神奇修復! **正在測試** –

+0

@Dom:太好了!很高興它幫助:) –

+0

我從來沒有教過這樣一小部分的代碼可以修復它!我很驚訝 –

0

問題是你不能接受一堆隨機字節並將它作爲string投射。 string具有特定的結構,並且分配由編譯器管理。

我可以爲你重寫這一點,但我不認爲我會對你有任何好處,因爲我必須假定調用這個的代碼在內存管理方面沒有做得更好。

3

Kornel的得到了正確的想法。你也許可以進一步簡化它,就像這樣:

function TMidifile.ReadString(F: integer): AnsiString; 
begin 
    SetLength(Result, F); 
    Move(ChunkIndex^, result[1], F); 
    inc(chuncIndex, F); 
end; 

這將會使閱讀速度快了很多,特別是如果你使用移動的Fastcode版本(或最近的德爾福的版本附帶的Fastcode版本內置到RTL中。)

+1

+1:我不敢這樣做,因爲我沒有一個編譯器,方便測試它;> –

+0

@Mason:小心,因爲Dom可能會使用Delphi 2009或更高,移動然後移動字節,而不是字符。 –

+0

好點。編輯考慮到這一點。 –