2010-06-10 61 views
2

我想用C++打印一些东西。但是,我遇到了一个奇怪的错误,给我留下无能,我使用下面的代码:C++:怪异的分割错误

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; 
} 

的那一刻我去掉“诠释克;”我得到一个:“程序收到的信号SIGSEGV,分段错误。”我使用codeblocks和mingw编译器,都是最新的。什么可能导致这个?

+0

*其中*是否出现段错误? – jalf 2010-06-10 11:45:10

+0

你可以使用调试器吗? – 2010-06-10 11:48:46

+0

没有给出行号,调用堆栈只给出这个错误:ntdll!RtlLookupAtomInAtomTable() – Kleas 2010-06-10 11:49:36

回答

1

我不知道这是否是潜在的问题 - 但您应该始终初始化所有结构的成员(就像您使用PRINTDLG一样)。在DOCINFO结构中,lpszDataType成员未初始化。而不是使用ZeroMemorymemset,我更喜欢类似DOCINFO di = {0};

+0

或者以下大小为前缀的Win32结构体:'PRINTDLG pd = {sizeof(PRINTDLG)};' – MSalters 2010-06-10 13:10:32

6

这意味着你损坏了你的堆栈。您放入堆栈的整数恰好位于损坏的数据中。因此,通过将额外的整数放入堆栈中,您基本上会丢弃已损坏的内存。如果你没有放置足够的整数,那么你将覆盖诸如函数返回地址,寄存器栈支持等等,这很容易导致分段错误。

0

我已在Visual Studio中粘贴代码,取消注释行并将所有者设置为0 pd.hwndOwner = 0;并且我没有得到分段错误,也许你正在做其他更早的事情来破坏堆栈,并且当你把变量放在堆栈上时,你会得到错误?