为什么内存没有被释放?

时间:2013-12-24 03:01:15

标签: c++ memory-leaks

我正在尝试修复C ++中的内存泄漏,我对C ++比较陌生,所以也许是一个愚蠢的事情。我有一些代码需要一个屏幕捕获,我正在为Image我分配一些内存然后操作。以下是一些相关代码:

RGBTRIPLE* ScreenShot(char *BmpName, DWORD &height, DWORD &width, char* bmpToFree){
    DWORD FileSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+(sizeof(RGBTRIPLE)+1 * (Width*Height * 4));
    char *BmpFileData = (char*)GlobalAlloc(0x0040, FileSize);

    // Some code

    BitBlt(CaptureDC, 0, 0, Width, Height, DevC, 0, 0, SRCCOPY | CAPTUREBLT);
    GetDIBits(CaptureDC, CaptureBitmap, 0, Height, Image, (LPBITMAPINFO)BInfoHeader, DIB_RGB_COLORS);

    height = Height;
    width = Width;
    bmpToFree = BmpFileData;

    DeleteObject(CaptureBitmap);
    DeleteObject(CaptureDC);
}

正如您所看到的,我没有使用GlobalFree(BmpFileData)释放BmpFileData,因为我仍然需要在另一个方法中使用此数据,因此我保留一个引用将指针传递给此行中的另一个指针bmpToFree = BmpFileData; < / p>

所以现在我对这些数据做了一些工作,然后我就这样使用GlobalFree()

char* bmpToFree = NULL;

RGBTRIPLE *image = ScreenShot("Prueba.bmp", h, w, bmpToFree);
// Do some work
GlobalFree(bmpToFree);

但是就这样我有内存泄漏。如果我将GlobalFree(BmpFileData)放在Screenshot()方法中,我的泄漏就会消失,但我没有数据可以处理。

我做错了什么?

4 个答案:

答案 0 :(得分:5)

问题是bmpToFree应该是对指针的引用。

RGBTRIPLE* ScreenShot(.., char* bmpToFree)

应该是

RGBTRIPLE* ScreenShot(.., char* &bmpToFree)

或者你可以用另一种方式解决。

RGBTRIPLE* ScreenShot(.., char** bmpToFree)
{
   ...
   *bmpToFree = BmpFileData;
}

它们基本相同,无论是对变量(&)的引用(char *),还是对变量(*)的引用(char *)。当您需要更改传入的原始变量而不是副本时,可以使用它们。

答案 1 :(得分:2)

您正在将指针的值传递给函数 - 但是当它返回时,原始值不会更新。您需要传递对指针的引用 - 以便函数内的语句

 bmpToFree = BmpFileData;

实际更新调用例程中的变量。你可以通过传递指针的地址来做到这一点,即

&bmpToFree

要完成这项工作,您需要更改函数签名以期望指向指针

RGBTRIPLE* RGBTRIPLE* ScreenShot(char *BmpName, DWORD &height, DWORD &width, char** bmpToFree);

inside the function, you change the line to

 *bmpToFree = BmpFileData;

你用

来称呼它
RGBTRIPLE *image = ScreenShot("Prueba.bmp", h, w, &bmpToFree);

答案 2 :(得分:2)

据我所见,该函数应声明为:

RGBTRIPLE* ScreenShot(char *BmpName, DWORD &height, DWORD &width, char*& bmpToFree)

否则,指针的赋值仅仅是bmpToFree的本地副本,在函数返回后它不会保留。

答案 3 :(得分:1)

如果希望函数修改参数,则必须通过引用而不是值传递参数。您可以使用指针或引用,但最好是引用。

例如:

void add(int a, int b, int& result) {
   result = a + b;
}

(显然你会在现实生活中使用返回值,但这只是一个例子。)

void add(int a, int b, int* result) {
   *result = a + b;
}

不是这个:

void add(int a, int b, int result) {
   result = a + b; // Only local copy of result is modified
}

因此,在您的情况下,您正在尝试修改作为指针的参数的值。因此,您需要通过引用传递此参数,即char *&amp; bmpToFree