【问题标题】:Assertion Error断言错误
【发布时间】:2010-10-07 01:15:29
【问题描述】:

在 vc++6.0 MFC Application Project 中,我不会得到编译错误,但是当我运行该项目时,我会得到错误

调试断言失败! 程序:project.exe 文件:winocc.cpp 线路:345 有关您的程序如何导致断言的信息 失败,请参阅有关断言的 Visual C++ 文档。 (按重试调试应用程序)

这是什么错误,为什么会出现这种类型的错误,如何调试这个错误,请帮助任何机构,

【问题讨论】:

    标签: visual-c++


    【解决方案1】:

    您可能会发现 winocc.cpp 中的第 345 行有一个断言。查看该源文件以查看它正在检查的内容(您不应该做的事情),然后停止这样做 :-)

    如果您没有源代码,则必须:

    • 联系写它的人,找出断言是什么;或
    • 阅读 API 文档,看看您是否做错了什么。

    断言是一种运行时检查,编码器使用它来确保遵守规则或在造成任何实际损害之前发现意外情况。像双向链表这样的事情变得损坏(例如,像 assert (x->next->prev != x) 这样的事情,如果节点 A 的前一个节点没有节点 A 作为下一个节点,它将断言一个问题)。

    类似:

    Assert (p1 == NULL);
    

    (在我的神话语言中,以防我的 C 语法错误)如果 p1 等于 NULL,则函数开头将引发断言。

    网络搜索在第 345 行出现以下内容(请参阅 here):

    ASSERT(m_pCtrlSite != NULL); // 不是 OLE 控件(至少现在还不是)。

    您正在尝试动态创建许可的 ActiveX 控件,这似乎是一个问题。该链接还包含一个 KB 编号 Q151804,表示它是设计使然(这意味着 MS 可能不会修复它) - 您需要使用有效的许可证字符串创建控件。

    我发现的另一条评论指出:

    仅仅创建一个 ActiveX 控件的实例是不够的。 ActiveX 控件必须先正确托管,然后才能使用。你的不是。例如,您需要将其放在对话框中并创建该对话框的实例。

    如果没有看到您的其余代码,很难判断这是否是您的具体问题,但如果 your 第 345 行是我认为的问题,那是有道理的 - 它抱怨控制站点为 NULL(即,未托管该控件)。

    最后要注意的一件事:

    如果您的 ActiveX 控件在对话框中,您是否尝试在调用对话框的DoModal() 之前对控件进行操作

    该控件只会在您调用DoModal() 后进行初始化,因此在此之前您无法使用该控件。您应该在对话框OnInitDialog() 中执行此操作 - 此时,控件应该已完全初始化,您可以使用它做任何您想做的事情。

    如果您尝试使用对话框构造函数中的参数来操作控件,则需要将它们存储在 对话框 中的某个位置,然后将它们传输到 OnInitDialog() 中的控件。

    这些信息主要来自here

    【讨论】:

    • 如何直接找到winocc.cpp
    • 如果你有源代码,它应该在你的项目中的某个地方。查看我的更新答案(给我一两分钟)。
    【解决方案2】:

    “assert(...)”应该通过在运行时检查某些条件来帮助您发现 C++ 程序中的错误。您的程序中可能有一些未正确配置的内容导致此失败。就像 Pax 说的那样,看看你是否可以打开 winocc.cpp 并查看第 345 行以查看“断言”正在检查什么,看看你是否可以找出它失败的原因。

    通常,当您进行生产构建时,您将“编译”所有断言,这样它们就不会导致您的应用程序崩溃。

    【讨论】:

    • 即使是生产代码,我也总是留下断言。我宁愿让它们立即崩溃,也不愿在 100,000 条 CPU 指令之后引起一些晦涩的问题。安全胜过速度是我的口头禅之一。
    • 我同意,我认为编译断言有点愚蠢,它们显然是出于某种有用的原因,那么您为什么不想在生产代码中处理这些错误呢?
    • 问题是客户看到断言失败是绝对可怕的!这是一个他们不应该看到的神秘信息。您应该在生产代码中处理这些错误。通过使用适当的错误处理,例如通过异常。
    【解决方案3】:

    断言用于在运行时检查代码中的前置条件/​​后置条件和中间结果。

    很可能,您调用了一个函数/方法而不考虑所有先决条件,而这在运行时被检测到。

    在 VC 中,断言是在 Debug 目标上的二进制文件中引入的,而不是在 Release 目标上。

    【讨论】:

      【解决方案4】:

      如果它不是您控制的 dll(有时供应商会将断言留在调试库中),您可以显示反汇编并将断言的内存位置(中断的位置)从 3 更改为 90。这将改变你的 __asm int 3 到 __noop。有利于清除您可以摆脱的中断——至少对于那个调试会话来说是这样。 :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-08
        • 2018-05-19
        • 2014-09-27
        • 2014-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多