我正在创建一个简单的本机MFC应用程序,我正在使用Concurrency命名空间来执行一个简单的并行程序(绘制一个Mandelbrot集)。到目前为止,该程序非常基本,单击一个按钮并行绘制,另一个按顺序绘制。串行执行功能非常基本,并绘制正确的图片。和并行执行函数一样,但是当运行调试版本并退出程序时,输出告诉我存在内存泄漏。
以下是代码:
void CMandelbrotView::DrawSetParallel() {
// Get client area dimension which will be the image size
RECT rect;
GetClientRect(&rect);
//GetClientRect(pDC, &rect);
int imageHeight(rect.bottom);
int imageWidth(rect.right);
const double realMin(-2.1); // Minimum real value
double imaginaryMin(-1.3); // Minimum imaginary value
double imaginaryMax(+1.3); // Maximum imaginary value
// Set maximum imaginary so axes are the same scale
double realMax(realMin+(imaginaryMax-imaginaryMin)*imageWidth/imageHeight);
// Get scale factors to convert pixel coordinates
double realScale((realMax-realMin)/(imageWidth-1));
double imaginaryScale((imaginaryMax-imaginaryMin)/(imageHeight-1));
CClientDC hdc(this); // DC is for this view
OnPrepareDC(&hdc); // Get origin adjusted
critical_section cs; // Mutex for BitBlt() operation
parallel_for(0, imageHeight, [&](int y) // Iterate parallel over image rows
{
cs.lock(); // Lock for access to client DC
// Create bitmap for one row of pixels in image
HDC memDC = CreateCompatibleDC(hdc); // Get device context to draw pixels
HBITMAP bmp = CreateCompatibleBitmap(hdc, imageWidth, 1);
cs.unlock(); // We are done with hdc here so unlock
HGDIOBJ oldBmp = SelectObject(memDC, bmp); // Select bitmap into DC
double cReal(0.0), cImaginary(0.0); // Stores c components
double zReal(0.0), zImaginary(0.0); // Stores z components
zImaginary = cImaginary = imaginaryMax - y*imaginaryScale;
for(int x = 0; x < imageWidth; x++) // Iterate over pixels in a row
{
zReal = cReal = realMin + x*realScale;
// Set current pixel color based on n
SetPixel(memDC, x, 0, Color(IteratePoint(zReal, zImaginary, cReal, cImaginary)));
}
cs.lock(); // Lock to write to hdc
// Transfer pixel row to client area device context
BitBlt(hdc, 0, y, imageWidth, 1, memDC, 0, 0, SRCCOPY);
cs.unlock(); // Release the lock
SelectObject(memDC, oldBmp);
DeleteObject(bmp); // Delete bmp
DeleteDC(memDC); // and our working DC
});}
并行执行的代码与串行执行代码的不同之处在于它并行创建Mandelbrot映像的单独行,并使用临界区锁来确保线程不会在同一设备上下文句柄上进行争用。 / p>
现在我说有时报告内存泄漏的原因是因为运行发布版本不会导致报告内存泄漏。此外,当多次运行并行执行功能时,我并没有真正注意到更多的内存被用完,我有6GB的RAM以防万一有人想知道。 就性能而言,我的四核机器确实实现了串行执行计算+绘图速度的大约4倍的增长。 我也在msdn网站上看过类似的问题,但没有多大用处,因为这可能是一个VS bug。无论如何,我想要一个并行程序员的意见。
答案 0 :(得分:1)
我要说的是,为unique_ptr写一个快速删除函数,并将其用于您的资源。我能看到这个代码泄漏的唯一方法是投掷,但我没有看到任何抛出的地方。删除该漏洞后,我根本看不到任何泄漏。
答案 1 :(得分:1)
答案 2 :(得分:0)
您已经提到泄漏发生在“有时”并且并非总是如此。但是,代码中没有分支(特别是:使用内存分配进行分支),因此它应始终导致泄漏或永远不会导致泄漏。此外,正如我在评论中已经提到的,内存仅在memDc and bmp
的两个位置分配,并且您正在为这两个变量正确地清理资源。
简单来说,我想说上面的代码没有泄漏:) 如果您的应用程序中确实存在泄漏,那么可能会出现在其他代码路径中。