Причиной для этого является необходимость хранить std::function
в векторе, а собственный вектор, который мы имеем в компании, в основном делает realloc, если ему требуется больше памяти. (В основном просто memcpy
, оператор копирования/перемещения не участвует)
Это означает, что весь элемент, который мы можем положить в наш контейнер, должен быть тривиально-скопирован.
Вот какой код для демонстрации проблемной копии, которую я имел:
void* func1Buffer = malloc(sizeof(std::function<void(int)>));
std::function<void(int)>* func1p = new (func1Buffer) std::function<void(int)>();
std::function<void(int)>* func2p = nullptr;
*func1p = [](int) {};
char func2Buffer[sizeof(*func1p)];
memcpy(&func2Buffer, func1p, sizeof(*func1p));
func2p = (std::function<void(int)>*)(func2Buffer);
// func2p is still valid here
(*func2p)(10);
free(func1Buffer);
// func2p is now invalid, even without std::function<void(int)> desctructor get triggered
(*func2p)(10);
Я понимаю, что мы должны поддерживать копирование/перемещение элемента, чтобы сохранить std::function
безопасно.
Но мне все еще очень любопытно, что является прямой причиной недействительной копии std::function
выше.
-------------------------------------------- -------- UpdateLine ----------------------------------------- -----------
Обновлен образец кода.
Я нашел прямую причину этой неудачи, отлаживая наш внутренний вектор больше.
Тривиально скопированный std::function
имеет некоторую зависимость от исходной памяти объекта, удаление исходной памяти приведет к удалению сильно скопированного std::function
даже без уничтожения исходного объекта.
Спасибо всем за ответ на этот пост. Это все ценный вклад.:)