为什么记忆没有被释放

Why memory is not being freed?

本文关键字:释放 记忆 为什么      更新时间:2023-10-16

我正在尝试修复C++中的内存泄漏,我对C++相对较新,所以也许是一件愚蠢的事情。我有一些代码可以进行屏幕截图,并且我正在为我将要操作的图像分配一些内存。以下是一些相关代码:

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;

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

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

但是在这种方式上,我遇到了内存泄漏。如果我GlobalFree(BmpFileData)放在Screenshot()方法中,我的泄漏就消失了,但我没有数据可以处理。

我做错了什么?

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

RGBTRIPLE* ScreenShot(.., char* bmpToFree)

应该是

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

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

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

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

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

 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);

我所知,该函数应该声明为:

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

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

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

例如:

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*&bmpToFree。