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 成员未初始化。而不是使用ZeroMemorymemset,我更喜欢DOCINFO di = 0; 之类的东西

【讨论】:

或者对于那些以大小为前缀的 Win32 结构:PRINTDLG pd = sizeof(PRINTDLG) ;【参考方案3】:

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

【讨论】:

以上是关于C++:奇怪的分段错误的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中嵌入 python:奇怪的分段错误

C++:当我添加看似无关的代码行时,分段错误消失了

分段错误:在 C++ 中弹出向量时出现 11

指针数组 C++ 的分段错误

C++ 分段错误 OpenCV

在 C++ 中使用向量时出现分段错误