C++:奇怪的分段错误
Posted
技术标签:
【中文标题】C++:奇怪的分段错误【英文标题】:C++: Weird Segmentation fault 【发布时间】:2010-06-10 11:42:12 【问题描述】:我正在尝试使用 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 编译器。这可能是什么原因造成的?
【问题讨论】:
在哪里发生段错误? 没有给出行号,调用栈只给出这个错误:ntdll!RtlLookupAtomInAtomTable() 我不知道 DOCINFO 或 lpszDocName 是什么,但这行看起来很可疑:di.lpszDocName = "Test Print";也许需要一个 strcpy 和一些分配? @PeterK 我认为 lpszDocName 中的 lpsz 意味着 long(?) 指向字符串零终止的指针或类似的东西。 【参考方案1】:这意味着你破坏了你的堆栈。您放入堆栈的整数恰好位于损坏的数据中。因此,通过将额外的整数放在堆栈上,您基本上丢弃了损坏的内存。如果您没有放置足够多的 int,那么您将覆盖函数返回地址、寄存器的堆栈支持等内容,这很容易导致分段错误。
【讨论】:
【参考方案2】:我不知道这是否是一个潜在的问题 - 但您应该始终初始化结构的所有成员(就像您对 PRINTDLG
所做的那样)。在DOCINFO
结构中,lpszDataType
成员未初始化。而不是使用ZeroMemory
或memset
,我更喜欢DOCINFO di = 0;
之类的东西
【讨论】:
或者对于那些以大小为前缀的 Win32 结构:PRINTDLG pd = sizeof(PRINTDLG) ;
【参考方案3】:
我已将代码粘贴到 Visual Studio 中,取消注释该行并将所有者设置为 0 pd.hwndOwner = 0;而且我没有得到分段错误,也许您正在做其他事情来更早地破坏堆栈,当您将变量放在堆栈上时,您会收到错误?
【讨论】:
以上是关于C++:奇怪的分段错误的主要内容,如果未能解决你的问题,请参考以下文章