Reputation: 179
I'm trying to run the code below:
#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 ;
}
but I keep getting the error "Win32Project1.exe has triggered a breakpoint.". When I press continue I endup with the error "Debug assertion failed". The error is happening on the "free(pinfo4)" line.
Any help would be most appreciated.
Additional Notes: also tried "delete [] pinfo4;"
Additional Notes: The program displays this when it breaks. It is not my code: https://drive.google.com/file/d/0BwFUfWkiqC7VZkdrU04zZ3pqZUU/view?usp=sharing
Upvotes: 0
Views: 207
Reputation: 11
You probably allocating less space than needed. Consider (theoretical) situation where dwNeeded = 5 and sizeof(PRINTER_INFO_4) = 4.
Your code will allocate single ( 5 / 4 == 1 ) PRINTER_INFO_4 and EnumPrinters will overrun supplied buffer. It is better to allocate exactly dwNeeded BYTEs and than reinterpret_cast them to PRINTER_INFO_4.
And, as marcinj said, you should use either malloc/free or new[]/delete[].
Upvotes: 0
Reputation: 145194
From the docs, emphasis added:
” the buffer must be large enough to receive the array of data structures and any strings or other data to which the structure members point. If the buffer is too small, the
pcbNeeded
parameter returns the required buffer size.
This means that buffer is not all array. Hence computing the number of array items and allocating only that can give you a too short buffer. Consider either just allocating bytes, or rounding up instead of down the division result.
Also, don't allocate with new
and deallocate with free
. That's formal UB. Instead, just use a std::vector
of bytes.
Upvotes: 1
Reputation: 1856
Can you try below code
#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 ;
}
Upvotes: 0
Reputation: 49976
Insted of free (pinfo4) ;
you should use delete[] pinfo4
. Use free
together with malloc
- and thats for C programs. In c++ use new
and delete.
Another strange thing about your code, you use: pinfo4->pPrinterName,
, but pinfo4
is an array, so you should use rather: pinfo4[0]->pPrinterName
, or some other index. Also make sure dwNeeded is non zero.
Upvotes: 2