【问题标题】:memset causes "vector iterators incompatible" errormemset 导致“向量迭代器不兼容”错误
【发布时间】:2013-02-10 15:46:53
【问题描述】:

目前正在开发我的 DirectX 游戏,并在常量缓冲区构造函数中使用 memset(0)(或 VS 中的 ZeroMemory 宏)来用零初始化所有值,它工作得很好。当我不小心尝试以这种方式初始化包含向量的其他一些结构时,就会出现问题。根据编译器(VS2010/VS2012),这会导致“向量迭代器不兼容”,std::vector::end 更精确。我可以理解 memset 可能会使向量迭代器无效,但是为什么在我将元素推回向量后“结束”迭代器无法正常工作。它不应该重新定位向量结束迭代器到正确的位置(在最后一个元素之后)吗?是否所有类型的 std::some_container::end 迭代器也受此影响?

#include <vector>

class MyClass
{
public:
    MyClass() { 
        memset(this, 0, sizeof(*this));
    }
    ~MyClass() {}
    std::vector<int>& GetData() { return m_data; }
    float            m_range;
private:
    std::vector<int> m_data;

};

int main()
{
    MyClass myClass;
    myClass.GetData().push_back(1);
    myClass.GetData().push_back(2);

    for (auto it = myClass.GetData().begin(); it != myClass.GetData().end(); it++)     
    {
        //stuff
    }
}

【问题讨论】:

  • 只是...不要...使用... memset。它......只是工作......
  • 好吧,不要使用memset 问题解决了。这不是火箭科学。
  • 究竟你想在构造函数中对*this 做一个memset 来完成什么?太可怕了。
  • memset(this, 0, sizeof(*this)); wtf?
  • memset(this, 0, sizeof(*this)); 是一种大规模杀伤性武器。

标签: c++ vector iterator memset


【解决方案1】:

你不应该memseting 任何带有构造函数的类的对象。

【讨论】:

  • 你不应该在 C++ 中使用memset
  • @Zoidberg 它有它的用途;但这肯定不是一个。
  • @Zoidberg 但你不能:)。只需查看您的标准库头文件。
【解决方案2】:

改为这样做:

class MyClass {
public:
    MyClass() : range{} { 

    }

    float range;
    std::vector<int> data;
};

永远不要使用memset,当然绝对不要使用this哦上帝。

专业提示:buy a good book.

【讨论】:

  • @MaximYegorushkin:有,否则float 将保持未初始化状态。
【解决方案3】:

std::vector 已经有一个可以正确初始化向量的默认构造函数。什么都不做有你想要的行为。使用 memset 只是具有未定义的行为。

如果你想将float 成员初始化为零,C++ 提供了如下代码:

MyClass() : m_range(0) {}

C++11也允许写float m_range = 0;,但是微软的编译器还没有实现这个功能。

mem* 函数是非常粗糙的工具,在 std::vector 这样的 C++ 结构中没有位置。诸如正确初始化、std::copystd::fill 之类的替代方案是出色的解决方案,因为它们不会践踏类型系统。

【讨论】:

    【解决方案4】:

    您的对象是在导致问题的 memset 之前构造的。

    以这种方式初始化对象在 C++ 中不是一个好方法

    【讨论】:

      猜你喜欢
      • 2012-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-15
      • 1970-01-01
      • 2011-08-11
      • 1970-01-01
      相关资源
      最近更新 更多