【问题标题】:c++ std::vector.insert crashes on debug but works on releasec++ std::vector.insert 在调试时崩溃,但在发布时有效
【发布时间】:2011-12-01 04:13:45
【问题描述】:

我的程序在这一行崩溃,但仅在调试版本中,它在发布版本中运行良好。

m_lstIds.insert(m_lstIds.begin() + indexInsert, ID);

'm_lstIds' 是 int 的 std::vector,'ID' 是 int。当程序崩溃时,m_lstIds 有 3 个项目(1、2、3)。 indexInsert 为“0”,ID 为“0”。

错误信息说:

Expression: vector iterator + offset out of range

我正在运行 Visual Studio 2010;我猜这与与 STL 优化冲突的不良项目设置有关。

编辑: 当我说:“适用于发布”时,我的意思是如果我为 i = 0..3 执行std::cout<<m_lstIds[i],我实际上会打印出 0,1,2,3。在调试版本中,当我尝试插入时它会崩溃。

编辑2: 我找到了答案!感谢大家的帮助。

这是最短的复制品。问题是我在构造函数中调用的memset 函数。因为m_lstItem 的构造函数是在memset 之前调用的,所以它将擦除向量中允许insert 正常工作的所有数据。

真正有趣的是它在发布中是如何工作的,而不是在调试中。如果有人能解释那部分,那就太好了。

struct SimpleList
{
  SimpleList()
  {
    memset(this, 0, sizeof(SimpleList));
    m_lstItem.push_back(0);
    m_lstItem.push_back(1);
    m_lstItem.push_back(2);
  }

  void Crash()
  {
    m_lstItem.insert(m_lstItem.begin() + 0, 3);
  }

  std::vector<int>m_lstItem;
};

int main(int argc, char** argv[])
{ 
  SimpleList sl;
  sl.Crash();
  return 0;
}

【问题讨论】:

  • 您确定容器包含三个元素并且索引为 0 吗?它在发布中“工作”的事实意味着代码实际上已损坏,但如果没有运行时检查,您不会收到任何错误。
  • 向我们展示您的代码的工作示例,我们很难弄清楚向量是如何修改、使用等的。
  • 我无法重现该问题。需要查看完整代码。
  • 我相信您没有初始化在发布版本中设置为 0 和在调试版本中设置为 0xcdcdcdcd 的变量或其他一些垃圾,最终引用无效索引。如果您没有正确初始化“i”变量(使用 0),这将是可能的。啊,不,对不起,你在插入时说..你也可以检查一下:)
  • memset(this, 0, sizeof(SimpleList)); 除非您的班级是 POD,否则不要这样做! std::vector 必须使用自己的构造函数进行初始化。

标签: c++ visual-studio-2010 vector iterator


【解决方案1】:
当您的结构不是 POD 时,

memset(this, 0, sizeof(SimpleList)); 是不安全的。

由于成员 std::vector&lt;int&gt;m_lstItem;,您的结构不是 POD。

因此,在这种情况下,使用memset不安全,并导致未定义的行为。换句话说:任何事情都可以发生! 任何事情都包括按预期工作......

我的建议:除非你完全知道自己在做什么,否则不要在 C++ 中使用 memset

【讨论】:

  • 这确实回答了我的问题,但你的答案是在我自己发现问题后发布的:-)
  • @Twelvethousand 它是在您发布完整代码之后发布的。任何专家都会在阅读后几秒钟内指向 memset。
【解决方案2】:

我猜程序运行时 indexInsert 不为 0。 并且当向量在 DEBUG 模式下超出范围时,向量会抛出异常,而在 RELEASE 模式下则不会。 所以给你看完整的代码。

【讨论】:

  • 你是对的,不能 memset 包含 STL 变量的结构;我之前犯了错误,因为你是 :-)
猜你喜欢
  • 1970-01-01
  • 2018-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-08
相关资源
最近更新 更多