【问题标题】:Why does my program crash at the return statement?为什么我的程序在 return 语句处崩溃?
【发布时间】:2023-03-12 11:15:01
【问题描述】:

执行以下代码时出现异常

bool FieldValueMessage::Get(const std::string &field, double & value)
{
    string text;
    if(Get(field,text))
    {
        std::stringstream sstr(text);
        sstr >> value;
        if(sstr.fail())
            return false;
        else
            return true;
    } 
    else 
    {
        return false;
    }        
} 

获取函数如下

bool HashMapMessage::Get(const std::string &field, std::string & value)
{
    Field2Value::iterator i = f2v.find(field);
    if(i==f2v.end()){
        return false;
    } else {
        value = i->second;
        return true;
    }
}

Get 函数的调用者。我在这里没有发现任何问题。

for(i=quote_fields.begin(),j=0;i!=quote_fields.end();i++,j++){
    if (msg->Get((*i).c_str(),tmp)){
        if(tmp>0 && x->staging_data[j+1]!=tmp){
            x->staging_data[j+1] = tmp;
            has_update = true;
        }
    }
}

调用栈是

ntdll.dll!_RtlpCoalesceFreeBlocks@16()  + 0x35 bytes    
ntdll.dll!_RtlFreeHeap@12()  + 0x91f bytes  
msvcr90.dll!_free()  + 0xcd bytes   
msvcp90.dll!std::locale::`scalar deleting destructor'()  + 0x19 bytes   
msvcp90.dll!std::ios_base::_Ios_base_dtor()  + 0x39 bytes   
msvcp90.dll!std::basic_stringstream<char,std::char_traits<char>,std::allocator<char> >::`vbase destructor'()  + 0x19 bytes  
asapGeneric.dll!asap::FieldValueMessage::Get(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & field="ASK", double & value=0.055000000000000000)  Line 33 + 0x17 bytes   C++
_hdf.pyd!asap::TradeAndQuoteNormalizer::ParseQuote(asap::FieldValueMessage * msg=0x027194c0, asap::TAQ * taq=0x02716908)  Line 84 + 0x36 bytes  C++

字段的值为“ASK”。

这段代码运行良好,没有任何问题,但现在我在“return true”语句中遇到异常。

当我调试程序时...sstr.fail() 返回false。指针出现在return true; 语句上。此时,当我执行单个步骤时,突然出现未处理的异常:从位置 xxxxx 读取访问冲突。我从未在 return 语句中看到异常。在这种情况下有什么不正确的?这个 c++ 程序是从 python 脚本调用的。

【问题讨论】:

  • 如果析构函数抛出异常,您可能会在 return 语句周围出现异常(析构函数抛出异常通常不是好习惯)。话虽如此,唯一应该破坏的东西是string text和stringstream sstr,它们扔起来会很奇怪。错误的原因可能在于您的代码中某些不直接相关的位正在执行诸如缓冲区溢出或写入错误的内存之类的操作,而问题恰好出现在这里。
  • 向我们展示 Get(string,double) 的调用者
  • x-&gt;staging_data[j+1] = tmp; - 你确定staging_data 的长度足以容纳这么多数据吗?加法:msg-&gt;Get((*i).c_str(),tmp) - 你为什么在这里使用c_str?看起来没有它应该可以正常工作。
  • 基于该调用堆栈,看起来堆之前已被丢弃,但直到堆尝试将两个空闲块合并在一起时才触发异常。
  • 只是为了让事情变得清楚:在通常的意义上,您没有遇到异常;该程序正在崩溃。 (是的,我知道 MSVS 的某些配置会混淆两者,并最终在代码崩溃时生成异常。)

标签: c++ exception-handling


【解决方案1】:

以上帖子的答案实际上是有关该问题的cmets的集合。不止一个回复帮助我找到了解决方案。上述情况的问题是我没有正确初始化暂存数据。它应该是一个大小与 quote_fields 相同的数组,但它被初始化为长度 1。所以第一个元素已正确更新,但在 quote_fields 数组中的第二个元素被读取期间,我遇到了异常。 显然,只要我尝试访问不正确的元素,就不会引发异常。异常来自 stringstream 析构函数。根据 Retired Ninja,异常不会立即引发,而只会在堆尝试在稍后合并 2 个空闲块之前引发,如调用堆栈中所示。

【讨论】:

    猜你喜欢
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多