Структура memset с std::string
У меня есть массивная структура, где все содержимое является скалярными переменными, перечислениями и массивами скаляров (на основе стека), за исключением одной переменной std::string.
Теперь, вот мой вопрос...
Могу ли я изменить структуру на 0 по всему ее размеру (например, если бы это были просто все скаляры), или это невозможно при наличии std::string? Я не уверен, что memset сделает с его внутренним представлением.
И если вы собираетесь сказать, что это хорошо/плохо, пожалуйста, объясните, почему - я хотел бы знать, почему это так:)
Ответы
Ответ 1
Нет, вы не можете, он перепишет внутреннее состояние строки и сделает плохие вещи. Вы могли бы обернуть все элементы POD в отдельной структуре и поместить это в свой текущий, таким образом, вы могли бы установить memset и позволить построить по умолчанию конструкцию.
Изменить:. Чтобы пояснить, строка почти наверняка будет хранить указатель на память, выделенную для хранения. Конструктор строк всегда будет запущен, прежде чем вы сможете его memset (даже если вы memset this
в конструкторе вашего типа, сначала будет запускаться конструктор строк). Таким образом, вы переписываете это значение указателя и вместо указания на его хранилище указатель на NULL или какое-то другое почти определенно недопустимое значение.
Ответ 2
Здесь экзотическая идея: предположим, что ваш класс Foo
имеет множество примитивных элементов, которые остаются неинициализированными в конструкторе Foo
, за исключением одной строки:
class Foo
{
int a;
double b;
std::string s;
};
Конструктор Foo::Foo()
будет правильно инициализировать строку, но это ничего не поделает. Итак, давайте обнулить память до того, как мы построим!
void * addr = ::operator new(sizeof(Foo));
std::memset(addr, 0, sizeof(Foo));
Foo * p = new (addr) Foo;
// later
p->~Foo();
::operator delete(addr);
Конечно, было бы проще просто инициализировать все члены до нуля в конструкторе, но, возможно, у вас есть собственные причины, по которым вы не хотите создавать пользовательский конструктор.