在C ++中管理对象时内存分配的逻辑问题

时间:2014-10-09 18:54:38

标签: c++ pointers memory memory-leaks hbitmap

我的功能设计有些问题,我找不到合适的解决方案(我是C ++的初学者)。

前几天,我问another question与此链接有关。

所以,我有一个能够进行屏幕捕获的功能。它完美地运作。 事实是我希望这个函数从我实现的类中返回一个Image对象。

基本上,它是:

class Image {
public:
    BYTE *bitPointer;
    int width;
    int height;
};

我的功能就像这样:

Image screenCapture(int width, int height) {

    HDC hdcTemp, hdc;
    BYTE* bitPointer;

    hdc = GetDC(HWND_DESKTOP);
    hdcTemp = CreateCompatibleDC(hdc);

    BITMAPINFO bitmap;
    bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
    bitmap.bmiHeader.biWidth = width;
    bitmap.bmiHeader.biHeight = -height;
    bitmap.bmiHeader.biPlanes = 1;
    bitmap.bmiHeader.biBitCount = 24;
    bitmap.bmiHeader.biCompression = BI_RGB;
    bitmap.bmiHeader.biSizeImage = 0;
    bitmap.bmiHeader.biClrUsed = 0;
    bitmap.bmiHeader.biClrImportant = 0;
    HBITMAP hBitmap = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL);
    SelectObject(hdcTemp, hBitmap);
    BitBlt(hdcTemp, 0, 0, width, height, hdc, 0, 0, SRCCOPY);
    ReleaseDC(HWND_DESKTOP, hdc);
    DeleteDC(hdcTemp);

    Image screen;
    screen.bitPointer = bitPointer;
    screen.width = width;
    screen.height = height;

    return screen;
}

使用CreateDIBSection创建的bitPointer实际上是指向我第一个像素值的指针(如果我理解的话)。

然后,我可以使用一个简单的循环:

for (int i = 0; i >= 0; i++) {
        cout << i << ": " << (int)screenCapture(1366, 768).bitPointer[0] << endl;
    }

这是我的问题。

我必须通过调用hBitmap释放DeleteObject(hBitmap),否则我将没有更多的内存空间(并且循环最终崩溃)。

但是,我不知道哪里

我想在我的功能中执行此功能,但如果我拨打DeleteObject(),那么它也会破坏我的bitPointer,因此我将无法访问Image中的像素对象返回。 事实上,我对bitPointer变量是指针的事实感到有点困惑。这意味着我无法复制它以防止它被破坏。我找不到解决方案。

我尝试了两种解决方案:

  • 为我的班级DeleteObject()创建一个调用Image的析构函数 它不起作用,因为析构函数是从函数调用的,而不仅仅是从我的循环内部调用。
  • 将属性HBITMAP hBitmap添加到我的班级Image,然后从我的循环中调用DeleteObject()
    这不是很方便,而且我必须声明一个新的Image对象,我不能像在我写的循环中那样匿名地进行。

所以,我被困住了,有人可以帮我吗?

1 个答案:

答案 0 :(得分:1)

您可以将hBitmap作为参数传递给screenCapture函数。

screenCapture(int width, int height, HBITMAP& hBitmap)

这样你就可以在不想干扰Image成员的情况下销毁它。您在 screenCapture 函数之外声明了一个“空”hBitmap,并将其作为参数传递。该函数将使用引用来创建对象,并且在完成使用 bitPointer 值后,您将能够在screenCapture之外将其销毁。

如果需要存储所有屏幕截图,则需要实现工作缓冲区,因为内存有限。

相关问题