memset导致"矢量迭代器不兼容"错误

-8 c++ iterator vector memset

目前正在使用我的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
    }
}
Run Code Online (Sandbox Code Playgroud)

R. *_*des 7

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

如果要将float成员初始化为零,C++提供的代码如下所示:

MyClass() : m_range(0) {}
Run Code Online (Sandbox Code Playgroud)

C++ 11也允许编写float m_range = 0;,但Microsoft的编译器尚未实现此功能.

这些mem*函数是非常粗糙的工具,在C++结构中没有地位std::vector.正确初始化等替代方案std::copy,并且std::fill是优秀的解决方案,因为它们不会践踏类型系统.