【问题标题】:C++ Parameter's Value Changes Between Stack Frames in std::vectorstd::vector 中堆栈帧之间的 C++ 参数值变化
【发布时间】:2010-09-30 19:15:05
【问题描述】:

我遇到了一个非常奇怪的错误,希望有人能解释一下。我有一个简单的std::vector<V3x>,其中V3x 是一个3d 向量(线性代数类型)。以下代码会引发std::length_error 异常:

std::vector<V3x> vertices;
int vertexCount = computeVertexCount();
vertices.resize(vertexCount); // throws std::length_error

我已经验证computeVertexCount() 返回的值是35,它远低于vector::max_size(),所以它不可能要求太多的内存。

我将异常追溯到std::vector的定义,到以下两个函数。

void resize(size_type _Newsize, _Ty _Val)
    {   // determine new length, padding with _Val elements as needed
    if (size() < _Newsize)
        // NOTE: here, _Newsize - size() = 35
        _Insert_n(end(), _Newsize - size(), _Val); 
    else if (_Newsize < size())
        erase(begin() + _Newsize, end());
    }

void _Insert_n(const_iterator _Where,
    size_type _Count, const _Ty& _Val)
    {   // insert _Count * _Val at _Where
        // NOTE: here, _Count = 3435973836
        ...
    }

所以当_Count 参数在resize()_Insert_n() 之间传递时,值会从35 变为3435973836。我假设内存已经以某种方式损坏,但我不知道这是怎么回事。

如果它是问题的一部分,请提供更多上下文,此代码位于我从 Softimage XSI 加载的 .dll 插件中。

有谁知道什么可能导致这样的事情发生?

编辑:解决方案

nobugz,我可以吻你。

由于 VS2008 中的 _HAS_ITERATOR_DEBUGGING,std::vector 的大小在我的 .dll 中发生了变化。搜索将我带到someone with the same problem,并通过在我的项目顶部添加以下内容来修复它:

// fix stack corruption errors caused by VS2008
#define _HAS_ITERATOR_DEBUGGING 0
#define _SECURE_SCL 0

【问题讨论】:

  • 是 std::vector 顶点;真的是局部变量吗?否则,它很可能尚未创建(因为静态初始化惨败)
  • 是否 vertices.resize(vertexCount);需要第二个参数吗?

标签: c++ debugging memory parameters vector


【解决方案1】:

值 3435973836 很重要。在十六进制中,即 0xcccccccc。这是堆栈帧初始化代码在调试模式下分配给局部变量的值。当您在调试时看到它时,您会说“啊,变量未初始化”。也许这会让你更接近解决这个问题。

你提到了 DLL。这也有关系。迭代器调试可能会给您带来麻烦,您不能将已关闭的代码与未关闭的代码混合使用。由于 DLL 可能是在没有它的情况下编译的,请尝试 #define _HAS_ITERATOR_DEBUGGING 0。

【讨论】:

  • 始终查看意外非常大值的十六进制表示。他们经常告诉你,你已经进入了从未有过的地方,就像这个。
【解决方案2】:

每当参数或局部变量意外更改时,很有可能是由于堆栈损坏。每当您使用未初始化的局部变量或存储超出分配给本地字符串或数组的内存的数据时,都会发生这种情况。

一个简单的调试方法:

  1. 将您的程序加载到调试器中。
  2. 在有问题的函数的第一行代码处插入断点。
  3. 执行程序直到遇到断点。
  4. 对意外更改的变量设置监视。
  5. 单步执行函数,直到发生意外更改。

当写入未分配(或错误分配)的内存时,将发生更改。写入的目标是有问题的变量。

【讨论】:

    【解决方案3】:

    发布的代码是正确的,您可以假设 std::vector 没有错误。在最纯粹的环境中复制异常(新的空白项目)。 ComputeVertexCount() 中的 like this 会是愚蠢的吗?

    【讨论】:

      【解决方案4】:

      我建议查看为相关项目配置的 C++ 选项。确保它们都共享相同的对齐和运行时设置。您是否正在构建所涉及的 .DLL?

      【讨论】:

        【解决方案5】:
        猜你喜欢
        • 2012-12-13
        • 2019-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-22
        • 2019-01-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多