-8

目前正在处理我的 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
    }
}
4

4 回答 4

7

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

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

MyClass() : m_range(0) {}

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

这些mem*函数是非常粗糙的工具,在 C++ 结构(如std::vector. 诸如正确初始化、std::copy和等替代std::fill方案是更好的解决方案,因为它们不会践踏类型系统。

于 2013-02-25T13:27:19.860 回答
3

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

于 2013-02-25T13:24:48.553 回答
2

改为这样做:

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

    }

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

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

专业提示:买一本好书

于 2013-02-25T13:26:47.143 回答
0

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

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

于 2013-02-25T13:28:03.983 回答