Я получаю ошибки сегментации, когда использую оператор = -o для копирования структуры, содержащей std :: vector, в неинициализированную память.
Критический код выглядит так:
template<typename T>
ComponentContainer
{
T* buffer;
size_t capacity;
size_t m_size;
public:
ComponentContainer();
~ComponentContainer();
size_t size();
void resize(size_t size);
T & operator[](size_t index);
};
template<typename T>
void ComponentContainer<T>::resize(size_t newSize)
{
if(this->m_size >= newSize)
{
this->m_size = newSize;
}
else
{
if(this->capacity < newSize)
{
const size_t newCapacity = capacity*2;
T* newBuffer = (T*)malloc(newCapacity*sizeof(T));
for(size_t i = 0; i<m_size; i++)
{
// checks if this->buffer[i] is valid intialized memory
if(pseudo_checkIfElementIsInitialized(i))
{
// when this is uncommented no segfault happens
//new (&newBuffer[i]) T();
newBuffer[i] = this->buffer[i]; // <- segfault happens here
}
}
this->capacity = newCapacity;
free(this->buffer);
this->buffer = newBuffer;
}
this->m_size = newSize;
}
}
T
-тип - это структура с std :: vector структур, когда я получаю segfault.
Я подозреваю, что std :: vector = -operator каким-то образом использует левую переменную newBuffer[i]
, и происходит ошибка сегментации, поскольку newBuffer[i]
не инициализируется.
Объекты будут создаваться только при новом размещении с функцией T & operator[](size_t index)
. Malloc должен только распределять память, ничего не инициализируя.
Я пытался написать простой пример, но он не удался:
#include <iostream>
#include <vector>
struct Hello
{
Hello()
{
std::cout << "constructor" << std::endl;
}
~Hello()
{
std::cout << "destructor" << std::endl;
}
std::vector<double> v = std::vector<double>(1);
};
int main()
{
Hello* buffer = (Hello*)malloc(1*sizeof(Hello));
char* noise = (char*)buffer;
for(size_t i = 0; i<sizeof(Hello); i++)
{
noise[i] = 100;
}
auto tmp = Hello();
tmp.v[0] = 6.6;
//new (&buffer[0]) Hello();
buffer[0] = tmp;
std::cout << buffer[0].v[0] << std::endl;
return 0;
}
Работает нормально, без segfault. Я предполагаю, что это потому, что неинициализированная память была просто случайной для операции std :: vector = -o.
Итак
а) верна ли эта теория
и если да
б) как решить эту проблему без использования конструктора по умолчанию (T()
) для каждого класса, который я использую в качестве T
для моего ComponentContainer