tags:

views:

150

answers:

3

I am trying to print something using C++. However, I am running into a strange bug that has left me clueless, I use the following code:

PRINTDLG pd;
ZeroMemory(&pd, sizeof(pd));
pd.lStructSize = sizeof(pd);
pd.Flags = PD_RETURNDEFAULT;
PrintDlg(&pd);

// Set landscape
DEVMODE* pDevMode = (DEVMODE*)GlobalLock(pd.hDevMode);
pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
pd.hwndOwner = mainWindow;
pd.Flags = PD_RETURNDC | PD_NOSELECTION;
GlobalUnlock(pd.hDevMode);

if (PrintDlg(&pd))
{
    DOCINFO di;

    di.cbSize       = sizeof(DOCINFO);
    di.lpszDocName  = "Test Print";
    di.lpszOutput   = (LPTSTR)NULL;
    di.fwType       = 0;

    //start printing
    StartDoc(pd.hDC, &di);

    int a;
    int b;
    int c;
    int d;
    int e;
    int f;
    // int g; // Uncomment this -> CRASH

    EndDoc(pd.hDC);
    DeleteDC(pd.hDC);
}
else
{
    cout << "Did not print: " <<  CommDlgExtendedError()  << endl;
}

The moment I uncomment 'int g;' I get a: "Program received signal SIGSEGV, Segmentation fault." I use codeblocks and the mingw compiler, both up to date. What could be causing this?

+6  A: 

That means that you corrupted your stack. The ints that you placed on to the stack happened to be in the corrupted data. So by placing the extra ints on the stack, you essentially discarded the corrupted memory. If you don't place on enough ints, then you will be overwriting things like function return addresses, stack backing of registers, and suchlike, which will easily cause a segmentation fault.

DeadMG
A: 

I have pasted the code in visual studio uncommented the line and set the owner to 0 pd.hwndOwner = 0; and I don't get the segmentation fault maybe you are doing something else to corrupt the stack earlier and when you put the variable on the stack you get the error ?

Olorin
+1  A: 

I don't know if this is a potential problem here - but you should always initialize all members of structures (like you did with the PRINTDLG). In the DOCINFO struct the lpszDataType member is uninitialized. Instead of using ZeroMemory or memset, I prefer something like DOCINFO di = {0};

humbagumba
Or in case of those size-prefixed Win32 structs: `PRINTDLG pd = { sizeof(PRINTDLG) };`
MSalters