memset的原因“矢量迭代器不兼容”的错误

问题描述:

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

#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 
    } 
} 
+6

只是...不要...使用... memset。它...只是工作... – 2013-02-25 13:24:21

+0

那么不要使用'memset'问题解决。这不是火箭科学。 – 2013-02-25 13:24:27

+1

你究竟想要在构造函数中对'* this'做一个memset?这是可怕的。 – 2013-02-25 13:24:30

你不应该是memset任何具有构造函数的类的对象。

+3

你不应该用C使用'memset'都++。 – 2013-02-25 13:25:01

+0

@Zoidberg它有它的用途;但这当然不是一个。 – 111111 2013-02-25 13:26:09

+0

@Zoidberg,但你不能:)。只要看看你的标准库头文件。 – 2013-02-25 13:27:04

而是执行此操作:

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

    } 

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

切勿使用memset,当然绝对不是this哦,上帝。

临提示:buy a good book

+2

@MaximYegorushkin:它有,'float'将被保留为未初始化。 – Xeo 2013-02-25 13:28:34

std::vector已经有一个正确初始化向量默认构造函数。无所事事有你想要的行为。使用memset只是有未定义的行为。

如果你想在float成员初始化为零,C++提供了与类似的代码如下:

MyClass() : m_range(0) {} 

C++ 11也允许写float m_range = 0;,但微软的编译器没有实现此功能尚未。

mem*函数是非常粗糙的工具,在C++构造中没有地方,如std::vector。像正确的初始化,std::copystd::fill等替代方案是优越的解决方案,因为它们不会践踏类型系统。

你的对象是导致问题的memset之前建造。

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