memset вызывает «несовместимые векторные итераторы» ошибка

В настоящее время работаю над моей игрой DirectX и использую memset (0) (или макрос ZeroMemory в VS, если хотите) в конструкторах константных буферов, чтобы инициализировать все значения нулями, и это прекрасно работает. Проблема возникает, когда я случайно попытался инициализировать другую структуру, содержащую вектор, таким образом. Согласно компилятору (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
}
}

-9

Решение

std::vector уже есть конструктор по умолчанию, который правильно инициализирует вектор. Бездействие — это поведение, которое вы хотите. С помощью memset просто имеет неопределенное поведение.

Если вы хотите инициализировать float член к нулю, C ++ обеспечивает это с помощью кода, подобного следующему:

MyClass() : m_range(0) {}

C ++ 11 также позволяет писать float m_range = 0;, но компилятор Microsoft пока не реализует эту функцию.

mem* функции — это очень грубые инструменты, которым нет места среди конструкций C ++, таких как std::vector, Альтернативы, такие как правильная инициализация, std::copy, а также std::fill являются превосходными решениями, потому что они не попирают систему типов.

7

Другие решения

Ты не должен быть memsetЛюбые объекты классов с конструкторами.

3

Сделайте это вместо этого:

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

}

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

Никогда не используйте memsetи, конечно, абсолютно не на this О Боже.

Pro совет: купить хорошую книгу.

2

Ваш объект создается перед memset, что вызывает проблемы.

Инициализация объекта таким способом не является хорошим подходом в C ++

0
По вопросам рекламы [email protected]