我正在尝试使用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;
}
我取消注意'int g;'的那一刻我得到一个:“程序接收信号SIGSEGV,分段错误。”我使用代码块和mingw编译器,都是最新的。可能是什么导致了这个?
答案 0 :(得分:6)
这意味着您损坏了堆栈。您放入堆栈的整数恰好位于损坏的数据中。因此,通过在堆栈上放置额外的int,您基本上丢弃了损坏的内存。如果你没有放置足够的整数,那么你将覆盖函数返回地址,寄存器堆栈支持等等,这很容易导致分段错误。
答案 1 :(得分:1)
我不知道这是否是一个潜在的问题 - 但你应该始终初始化所有结构成员(就像你使用PRINTDLG
所做的那样)。在DOCINFO
结构中,lpszDataType
成员未初始化。我更喜欢使用ZeroMemory
memset
或DOCINFO di = {0};
答案 2 :(得分:0)
我已在Visual Studio中粘贴代码,取消注释该行并将所有者设置为0 pd.hwndOwner = 0;并且我没有得到分段错误,也许你正在做其他事情来更早地破坏堆栈,当你把变量放在堆栈上时你会得到错误?