4

我遇到了一个非常奇怪的错误,我希望有人能解释一下。我有一个简单的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之间传递时,值从 35 变为 3435973836。我假设内存已以某种方式损坏,但我不知道这是怎么回事。resize()_Insert_n()

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

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

编辑:解决方案

nobugz,我可以吻你。

由于_HAS_ITERATOR_DEBUGGING在 VS2008 中,std::vector 的大小在我的 .dll 中发生了变化。搜索使我找到了遇到同样问题的人,并通过在我的项目顶部添加以下内容来解决此问题:

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

5 回答 5

22

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

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

于 2009-01-11T18:43:54.530 回答
2

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

一个简单的调试方法:

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

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

于 2009-01-11T18:26:34.393 回答
0

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

于 2009-01-11T17:55:05.517 回答
0

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

于 2009-01-11T18:25:34.083 回答
0

你可能会发现重新编译世界(一切)有帮助......

于 2009-01-11T19:46:29.317 回答