【问题标题】:Logical matter for memory allocation while managing my objects in C++在 C++ 中管理我的对象时内存分配的逻辑问题
【发布时间】:2014-12-04 19:51:37
【问题描述】:

我的函数设计有一些问题,我没有找到合适的解决方案(我是 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;
    }

这是我的问题。

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

但是,我不知道在哪里去做。

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

我尝试过的两种解决方案:

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

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

【问题讨论】:

  • 你没有对本地的BYTE* bitPointer;做任何事,而是将它分配给screen.bitPointer = bitPointer;
  • 为什么将“图像”类型作为整数返回?
  • 您可以添加 HBITMAP hBitmap 成员并按值返回“屏幕”。它不是很大,所以应该没问题。就像@DieterLücking 所说,为什么要打扰当地人呢?只需“CreateDIBSection”直接进入屏幕。如果位图和 HBITMAP 句柄相互绑定,它们应该在同一个结构/实例中,并且 'Image' dtor 可以取消它们。
  • @MartinJames 返回的 int 是复制/粘贴错误。 @DieterLücking,你说得对,我的本地 bitPointer 没用,谢谢。但是,您能否就您所谈论的内容提交一个答案?因为我不确定完全理解......实际上,我不明白 Image 析构函数如何有用,因为它本身永远不会调用 DeleteObject(),我必须这样做。最后,除了@VAndrei 的解决方案,我看不到任何其他解决方案。

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


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-18
    • 2015-08-17
    • 2017-07-31
    • 2021-06-10
    • 2018-03-31
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多