【问题标题】:C++: Weird Segmentation faultC++:奇怪的分段错误
【发布时间】: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(?) 指向字符串零终止的指针或类似的东西。

标签: c++ printing


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多