为什么会内存泄漏?极简单的代码。(100分)

  • 主题发起人 主题发起人 远帆
  • 开始时间 开始时间

远帆

Unregistered / Unconfirmed
GUEST, unregistred user!
一个非常简单的线程代码。可是竟然有内存泄漏,不明白为什么会出问题?
procedure tx.Execute;
var
n: Integer;
c: PChar;
begin
{ Place thread code here }
FreeOnTerminate := True;
GetMem(c, 200);
for n := 0 to 100do
begin
Sleep(50);
if Terminated then
Break;
end;

FreeMem(c);
Beep;
end;

下面是关于此种情况内存泄漏的解释。可是看了还是不明白。谁能帮我解释一下?
Thanks!
Description
A thread, which makes calls to one or more run-time library functions, was created using CreateThread. The program should have used _begin
threadex instead of CreateThread for the first C run-time library memory allocation. A thread that uses functions from the C run-time libraries should use the _begin
threadex and _endthreadex C run-time functions for thread management rather than CreateThread and ExitThread. Failure todo
so results in small memory leaks when ExitThread is called.
Note: If the run-time library is statically linked and the module lacks debug info, it may not be possible for the call to _begin
threadex to be detected and this error is reported. In this situation, the error can be safely suppressed.
Sample Code
...
DWORD WINAPI aThread(void *arg)
{
char *a = malloc (10);
free (a);
ExitThread(0);
}
void main()
{
int i;
DWORD id;
HANDLE hThread2[NUM_THREAD];
for (i = 0;
i < NUM_THREAD;
i++)
{
hThread2 = CreateThread(NULL, 0, aThread, NULL, 0, &amp;id);
}
WaitForMultipleObjects(NUM_THREAD, hThread2, TRUE, INFINITE);
for (i = 0;
i < NUM_THREAD;
i++)
{
CloseHandle(hThread2);
}
}
...
Repair
Use the C run-time functions _begin
threadex and _endthreadex to create and destroy threads, which use functions from the C run-time libraries.
 
按得太快。只给了100分,可能少了点。
如果解决了问题,我愿意再给200分。
 
提示内存泄漏的是这一句。
GetMem(c, 200);
似乎是还没有执行
FreeMem(c);
就提示泄漏了。
 
加上try finally试试呢,或者用AllocMem
祝你好运
 
好象是在线程里申请内存的问题,把内存申请放到线程之外试试
 
我晕了。怎么会用allocmem就好了?
我理解:getmem就是申请一段内存区域,但是这段内存域中的内容是不确定的,而allocmem
也是申请一段内存区域,但是这段内存区域被清零了。
但是这和内存泄漏有什么关系呢?
请rockjie解释一下?
我在程序是用new申请的内存,是不是把它清零就没有问题了?
我先试试。
不过还是请你解释原因,否则我寝食难安啊。

 
看一下
TerminateThread的帮助。
 
to 行素:
  没办法啊,我的程序是必需在线程中做动态内存申请的。上面的只是一个例子,不是我
的真正程序。
to wlmmlw:
  什么意思?能解释一下吗?
 
只能认为是你用的内存泄漏检查程序的一个很弱智的bug.
因为AllocMem内部调用的就是GetMem. 只不过Get完后它又调用了fillchar而已。
看你的例子程序中并没有对Getmem获得的内存进行写操作,是不是这个造成内存泄漏检查程序的误判?
 
AllocMem是从堆中分配内存。
 
谢谢老大关心。
我用的是boundschecker
并不是没有对内存进行操作造成的误判。
奇特的是我用getmem后然后fillchar也是同样报告内存泄漏。
就我的感觉bc似乎只执行到申请内存的地方就报错,跟本就没有执行后面的语句。
你是说这段程序没有问题?
但是保险起见,线程中还是用allocmem代替new和getmem好了,
因为我是做winsock通讯控件:)
 
to huawdg:
 啊?那getmem呢?
看看allocmem源码:
function AllocMem(Size: Cardinal): Pointer;
begin
GetMem(Result, Size);
FillChar(Result^, Size, 0);
end;

看来用allocmem和getmem再fillchar是一回事,那么boundschecker的确多少有些问题。
请问各位:
  如何查看程序占用内存的值呢?感觉nt的任务管器是不能准确查看内存占用值的。你
们用什么方法?
 
呵呵Another_eYes来了就可以给你解释清楚了,我只是经验之谈,
因为人家都说AllocMem最方便稳定
Another_eYes,给他们讲讲清楚吧,我也听着,哈哈
 
呵呵,我看内存没有泄露是软件的误报!!![:D]
 
还有,你干脆用
var
buf:array[0..199] of AnsiChar;
pbuf:pChar;
pbuf:=@buf,绝对没有任何问题,而且不用释放资源,速度快
 
procedure tx.Execute;
var
n: Integer;
c: PChar;
begin
{ Place thread code here }
FreeOnTerminate := True;
GetMem(c, 200);
for n := 0 to 100do
begin
Sleep(50);
if Terminated then

begin

Break;
FreeMem(c);
end;
FreeMem(c);
Beep;
end;
 
接受答案。看来是软件误报。
rockjie-90
行素-10
Another_eYes-100
张无忌-100
由于开始没忘了输入正确的分值,所以请 Another_eYes、张无忌 到
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1429439
拿分。
 
boundschecker 怎么用呀?
 

Similar threads

A
回复
0
查看
932
Andreas Hausladen
A
A
回复
0
查看
805
Andreas Hausladen
A
A
回复
0
查看
834
Andreas Hausladen
A
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
后退
顶部