清理内存分配问题 [英] Clean Up Memory Allocation Problems

查看:79
本文介绍了清理内存分配问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨那里,

我已经采用了一些代码,用图形做一些奇特的东西。

它用C ++编写并编译成可调用的DLL我可以在我的C#程序中使用。

(所有的c ++源代码都可用)



它很棒并且能够提供我需要的功能但它像一个筛子一样泄漏记忆。

我想我可以修复它并回馈开源社区,因为原作者目前忙于实际工作。 :)



问题是我的C ++相当平均但是嘿我可以谷歌了。我已经修复了一个喷射器,但是我看到了几块代码看起来像这样。



Hi There,
I have "adopted" some code that does some fancy stuff with graphics.
It is written in C++ and compiled into a callable DLL that I can use in my C# program.
(all the c++ source is available)

It works great and gives me exactly the features I need but it leaks memory like a sieve.
I figure I can fix it and give something back to the open source community as the original author is too busy with real work at the moment. :)

The trouble is my C++ is fairly average but hey I can google. I have fixed one gusher but I see a few blocks of code that look like this for example.

ImageData* ImageData::Clone()
{
	ImageData* img_data = new ImageData;		
	img_data->m_bytesPerPixel = m_bytesPerPixel;
	img_data->AllocDataSpace(GetWidth(), GetHeight(), GetBytesPerPixel() * 8);
	memcpy(img_data->m_data, m_data, GetSize());		
	img_data->m_width = m_width;
	img_data->m_height = m_height;

	return img_data;
}





我的理解是第一行中的新将分配一些内存并且必须在其他地方相应的删除img_data来释放内存。

我搜索了项目并且没有一个。



我希望用创建它的相同方法进行删除。

但是img_data正在返回到调用方法,所以我不能在那里删除它。



我假设这是泄漏,但我不知道如何处理它。

正确方向的任何sugestions / points非常有帮助。



预付谢谢

David



更新14Apr13

也许我并没有说清楚这一点。这里有一些更多的细节。我的c#代码将文件名传递给DLL中包含的c ++代码。 DLL中的代码计算文件中的文档是否已被直接扫描并返回文档的角度,如果它与c#代码是正方形,则为0。很清楚问题出在c ++代码中。

进一步的调查显示,下面显示的示例模块实际上从未被调用过。

如果有人想看代码那么是在这个代码项目文章和一个简单的示例VIsual Studio项目调用和测试DLL包括。



检测图像歪斜角度和歪斜校正图像 [ ^ ]



感谢您到目前为止的所有评论



My understanding is that the "new" in the first line is going to allocate some memory and there has to be a corresponding "delete img_data" somewhere else to deallocate the memory.
I searched the project and there isn''t one.

I''d expect to be doing the delete in the same method that created it.
But img_data is being returned to the calling method so I can''t delete it there.

I''m assuming that this is a leak but I don''t know how to deal with it.
Any sugestions / points in the right direction would be very helpfull.

Thanks in Advance
David

Update 14Apr13
Perhaps I didn''t make this clear enough. Here are some more details. My c# code passes a file name to the c++ code contained within the DLL. The code in the DLL calculates if the document in the file has been scanned straight and returnes the angle of the document or 0 if it is square to the c# code. So clearly the problems lies within the c++ code.
Further investigation revealed that the example module shown below is never actually called.
If anyone would like to look at the code it is in this Code Project Article and a simple example VIsual Studio project to call and test the DLL is included.

Detect image skew angle and deskew image[^]

Thanks for all your comments so far

推荐答案

当您调用API以实现其他内容的克隆时,调用代码将成为克隆的所有者。调用代码的责任是自行清理。如果发生内存泄漏,问题在于调用者,而不是克隆工厂。没有多少修复可以使这更好。



我会建议当''工厂''DLL退出时,不要自动执行内存操作任何其他时间。工厂方法的工作是生成克隆,而不是管理它的生命周期。如果在这里删除任何对象,可能会发生其他不好的事情。



解决方案#1是正确的,但可能没有完全说明。我建议解决方案#2是一堆废话。



如果你想找到并修复任何明显的内存泄漏,找出调用代码完成的位置克隆并删除它;其他地方。
When you call an API to make a clone of something else then really, the calling code becomes the owner of the clone. It is the responsibility of the calling code to clean up after itself. If a memory leak occurs, the problem lies with the caller, not with the clone factory. There is no amount of "fixing" that will make this better.

I would advise against doing something automatic with the memory when the ''factory'' DLL exits or any other time. The job of the factory method is to produce the clone, not to manage its lifetime. If any objects are deleted here, other bad things can happen.

Solution #1 is correct but perhaps not completely stated. I would suggest that Solution #2 is a bunch of nonsense.

If you want to find and fix any apparent memory leaks, figure out where the calling code is done with the clone and delete it there; nowhere else.


该方法的调用者必须删除(迟早)内存。但是,这应该在 DLL 本身内的某处完成。
The caller of that method must delete (sooner or later) the memory. However that should be done somewhere inside the DLL itself.


详细说明CPallini:



在同一个DLL中,你可以添加另一个函数,例如FreeMem(void * p)(它将在p上调用delete),一旦ImageData :: Clone()的调用者完成了他的工作,他就可以调用FreeMem(imageData)释放内存。
To elaborate CPallini:

In the same DLL, you can add another function say FreeMem(void* p) (which will call delete on p) and once the caller of ImageData::Clone() is done with his work, he can call FreeMem(imageData) to free the memory.


这篇关于清理内存分配问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆