【问题标题】:crash on a vector of vector only after a clear只有在清除后才会在向量的向量上崩溃
【发布时间】:2011-05-05 15:54:41
【问题描述】:

我对这段代码有疑问:它总是崩溃,但是当我发表评论时:dataResults[i].clear();

知道原因吗?

std::vector<std::string> r_OCRtoRetrieve;
std::vector<std::string> DBentries;

//stuff..

int distance = 9999; //TODO change here
int minDistance = 9999;

for(int i=0; i< r_OCRtoRetrieve.size(); i++)
    for(int j=0; j< DBentries.size(); j++)
    {
        distance = calcDistance( (const char *)r_OCRtoRetrieve[i].c_str(),(const char *) DBentries[j].c_str());

        if (distance == minDistance)
            dataResults[i].push_back(DBentries[j]);
        else
            if(distance < minDistance)
            {
                minDistance = distance;
                dataResults[i].clear();
                dataResults[i].push_back(DBentries[j]);
            }

    }

编辑:

发现错误..我必须初始化它..这是代码:

  for(int i=0; i< r_OCRtoRetrieve.size(); i++)
  {
    dataResults.push_back(std::vector<std::string>());

    for(int j=0; j< DBentries.size(); j++)
    {
      distance = calcDistance( (const char *)r_OCRtoRetrieve[i].c_str(),(const char *) DBentries[j].c_str());

      if (distance == minDistance)
    dataResults[i].push_back(DBentries[j]);
      else
    if(distance < minDistance)
    {
      minDistance = distance;
      if(dataResults[i].size() > 0)
        dataResults[i].clear();

      dataResults[i].push_back(DBentries[j]);
    }
    }

  } 

【问题讨论】:

  • 您能给我们异常消息吗?
  • 你的变量dataResults定义为什么?
  • 什么是dataResults?我没有看到声明。
  • 为什么在对calcDistance的调用中有多余的演员表?
  • 更重要的是dataResults是什么,它在哪里声明,数据是如何插入到其他地方的,访问dataResults[i]时确定它有i元素吗?跨度>

标签: c++ string vector crash


【解决方案1】:

很可能,您的向量dataResults 的大小小于i 的某个值

【讨论】:

    【解决方案2】:

    如果您遇到 index out of range 异常,可能是因为您的索引 i 超出了向量 dataResults 的范围

    如果这还不够明显,如果i 大于dataResults.size(),那么dataResults[i].clear(); 将抛出异常。

    编辑:

    考虑用 STL 迭代器替换基于索引的循环,并用 C++ 样式转换替换 c 样式转换。您的 if 语句也可以重新审视...

    编辑 2:

    因为您没有告诉我们异常是什么,但您有一个vector&lt;vector&lt;string&gt;&gt;,是对一个可能的问题的猜测吗?如果是这样,您需要在调用方法或构造循环之前检查要索引到有效位置的内容,以免索引超出范围。

    类似这样的:

    if (dataResults.size() > i)
    {
       // now we know dataResults[i] will be valid
       dataResults[i].clear();
       // etc
    }
    

    老实说,我可能会做更多类似的事情:

        typedef std::vector<std::string> StrArray;
        for(StrArray::const_iterator ret(r_OCRtoRetrieve.begin()); ret != r_OCRtoRetrieve.end(); ++ret)
        {
            // ret will be an const iterator to each string element in r_OCRtoRetrieve
            for(StrArray::const_iterator entry(DBentries.begin()); entry != DBentries.end(); ++entry)
            {
                // entry will be an const iterator to each string element in DBentries
                distance = calcDistance(ret->c_str(), entry->c_str());
    
                // init new StrArray in dataResults as needed
                // set new min distances as needed
                // push back strings to dataResults
                // whatever else you want to do
                // yata yata
            }
    }
    

    【讨论】:

    • 这是一个很好的解释,但它没有任何意义,因为海报说如果该行被注释掉,错误就会消失。下一行还索引 dataResults[i] ,这将引发相同的异常。
    • 更准确地说,你会得到未定义的行为
    • 我要捕获异常,因为没有任何消息.. 只是崩溃
    • "大于 datResults.size()", 挑剔的话应该大于或等于
    • 我添加了:if(dataResults.size() > 0) dataResults[i].clear();但同样的问题
    【解决方案3】:

    开始时 DataResults 中有什么?任何事物?如果不是,那么第一次通过时,当距离小于 9999 时,代码将尝试清除第一个、第零个索引处不存在的位置并抱怨。

    如果您进行调试构建,您应该会收到一条有意义的消息。

    【讨论】:

    • 当我开始时,我只有 std::vector > dataResults;嗯你的解释很有道理......我要去检查
    • 很遗憾我现在做不到。我尝试尝试捕获但没有输出
    • 你的意思是 if(dataResults.size() > 0) 吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多