【问题标题】:C++, win32 errorC++,win32错误
【发布时间】:2015-02-25 12:30:56
【问题描述】:

我正在尝试运行以下代码:

#include "stdafx.h"
#include <windows.h>
#include <winspool.h>
HDC GetPrinterDC (void)
{
    DWORD dwNeeded, dwReturned ;
    HDC hdc ;
    PRINTER_INFO_4 * pinfo4 ;


        EnumPrinters (PRINTER_ENUM_LOCAL, NULL, 4, NULL,
            0, &dwNeeded, &dwReturned) ;
        pinfo4 = new PRINTER_INFO_4 [dwNeeded/sizeof(PRINTER_INFO_4)] ;
        EnumPrinters (PRINTER_ENUM_LOCAL, NULL, 4, (PBYTE) pinfo4,
            dwNeeded, &dwNeeded, &dwReturned) ;
        hdc = CreateDC (NULL, pinfo4->pPrinterName, NULL, NULL) ;
        free (pinfo4) ;

    return hdc ;
}

但我不断收到错误“Win32Project1.exe 已触发断点。”。当我按继续时,我最终得到错误“调试断言失败”。 错误发生在“free(pinfo4)”行。

任何帮助将不胜感激。

附加说明:也试过“delete [] pinfo4;”

附加说明:程序中断时会显示此内容。这不是我的代码: https://drive.google.com/file/d/0BwFUfWkiqC7VZkdrU04zZ3pqZUU/view?usp=sharing

【问题讨论】:

  • 试试delete [] pinfo4;而不是free
  • 不,仍然出现错误
  • @behnam:你真的重建了这个项目吗?错误如何变化?
  • 如果 dwNeeded 不能被 sizeof(PRINTER_INFO_4) 整除会怎样?你最终会跑过分配的内存......
  • @antipattern,它在文档中哪里说 dwNeeded 需要被 sizeof(.) 整除?再看看:msdn.microsoft.com/en-us/library/windows/desktop/…缓冲区必须足够大以接收数据结构数组以及结构成员指向的任何字符串或其他数据。它可能在最后使用内存来存储字符串或其他信息。

标签: c++ winapi


【解决方案1】:

free (pinfo4) ; 中,您应该使用delete[] pinfo4。将freemalloc 一起使用——这适用于C 程序。在 C++ 中使用 newdelete.

你的代码还有一个奇怪的地方,你使用:pinfo4-&gt;pPrinterName,,但pinfo4 是一个数组,所以你应该使用:pinfo4[0]-&gt;pPrinterName,或者其他一些索引。还要确保 dwNeeded 不为零。

【讨论】:

【解决方案2】:

从文档中,强调了:

缓冲区必须足够大以接收数据结构数组以及结构成员指向的任何字符串或其他数据。如果缓冲区太小,pcbNeeded 参数会返回所需的缓冲区大小。

这意味着缓冲区不是所有的数组。因此,计算数组项的数量并只分配可能会给你一个太短的缓冲区。考虑仅分配字节,或将除法结果舍入 up 而不是 down


另外,不要使用new 分配并使用free 取消分配。那是正式的UB。相反,只需使用 std::vector 字节。

【讨论】:

  • 啊我认为这是解决方案。应该改用这个:pinfo4 = new PRINTER_INFO_4 [dwNeeded] ;
  • @behnam,不。你应该使用这个:pinfo4 = (PRINTER_INFO4*)new unsigned char[dwNeeded];
  • 为什么在我尝试释放资源时缩小缓冲区会导致错误?
  • @behnam:缓冲区太小会导致被调用函数写入超出缓冲区的末尾(因为原始代码告诉它缓冲区大于保证的大小)。写完之后,缓冲区溢出,可能会产生各种令人讨厌的影响。这只是一般的UB。
【解决方案3】:

你可以试试下面的代码

#include "stdafx.h"
#include <windows.h>
#include <winspool.h>
HDC GetPrinterDC (void)
{
    DWORD dwNeeded, dwReturned ;
    HDC hdc ;
    PRINTER_INFO_4 * pinfo4 ;


        EnumPrinters (PRINTER_ENUM_LOCAL, NULL, 4, NULL,
            0, &dwNeeded, &dwReturned) ;
        if (dwNeeded <= 0)
            return NULL;
        pinfo4 = new PRINTER_INFO_4 [dwNeeded/sizeof(PRINTER_INFO_4)] ;
        EnumPrinters (PRINTER_ENUM_LOCAL, NULL, 4, (PBYTE) pinfo4,
            dwNeeded, &dwNeeded, &dwReturned) ;

        hdc = CreateDC (NULL, pinfo4[0]->pPrinterName, NULL, NULL) ;
        delete [] pinfo4 ;

    return hdc ;
}

【讨论】:

  • 错误 C2819: 类型 '_PRINTER_INFO_4W' 没有重载成员 'operator ->' 和错误 2 错误 C2232: '->_PRINTER_INFO_4W::pPrinterName' : 左操作数有 'struct' 类型,使用'.'
【解决方案4】:

您分配的空间可能比需要的少。考虑(理论上)dwNeeded = 5 和 sizeof(PRINTER_INFO_4) = 4 的情况。

您的代码将分配单个 ( 5 / 4 == 1 ) PRINTER_INFO_4 并且 EnumPrinters 将超出提供的缓冲区。最好准确分配 dwNeeded BYTE,而不是将它们重新解释为 PRINTER_INFO_4。

而且,正如 marcinj 所说,您应该使用 malloc/free 或 new[]/delete[]。

【讨论】:

    猜你喜欢
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    • 2013-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多