Почему структуры, хранящие простые указатели на внутреннюю память, не могут храниться в контейнерах stxxl?
В stxxl FAQ я нашел следующее:
Параметризация контейнеров STXXL
Типы контейнеров STXXL, такие как stxxl:: vector, могут быть параметризованы только с типом значения, который является POD (то есть без виртуальных функций, нет пользовательское назначение копии / деструктор и т. д.) и не содержит ссылки (включая указатели) на внутреннюю память. Как правило, " сложный" типы данных не удовлетворяют этим требованиям.
Вот почему
stxxl::vector<std::vector<T> >иstxxl::vector<stxxl::vector<T> >являются недействительными. При необходимости используйтеstd::vector<stxxl::vector<T> >, или эмулировать двумерный массив с помощью делаем расчет индекса.
Невозможность использовать stxxl::vector<std::vector<T> > имеет смысл, поскольку контейнеры stxxl не вызывают конструкторы или деструкторы содержащихся элементов при изменении размера контейнера. Но как насчет хранения структуры, подобной этой:
struct S {
int* a;
}
Если я гарантирую, что объект, на который указывает a, действителен до тех пор, пока существует экземпляр stxxl::vector<S>, то в чем проблема хранения этого struct в stxxl::vector<S>? Если конкретный экземпляр S должен быть перемещен на диск, то значение указателя a записывается на диск. Позже значение указателя будет восстановлено, и я смогу его использовать. Очевидно, что значение указателя зависит от машины и экземпляра, но является ли это вопросом , даже если я забочусь о времени жизни указанного объекта? Я не отправляю сериализованный объект через сокет и не сохраняю сериализованный объект в базе данных для последующего использования.
Есть Ли Я чего-то не хватает?
EDIT: кто-то напомнил мне, что stxxl не копирует указатель, и поэтому я могу получить указатель на мусор, когда я получу экземпляр struct S позже. Я знаю, что. Я гарантирую, что этот пункт действителен в течение всего срока действия программы.
3 ответа:
(включая указатели) на внутреннюю память
Это означает указатель на элемент структуры, или иначе указатель в память, которой управляет контейнер. Например, у вас есть
struct Foo { int *a; int b; }; Foo f; f.a = &f.bПоскольку
f.aтеперь указывает на член структуры, и эта структура может быть скопирована, указатель может быть недействительным. Аналогично, если указатель указывает на любую другую структуру Foo, управляемую контейнером, который также можно перемещать.Если у вас просто есть указатель, и Управляй тем, на что он указывает, у тебя все будет хорошо.
В реализациях сстрогой безопасностью указателя тот факт, что вы сохранили указатель на диск, недостаточен. Если этот указатель больше не находится в памяти, объект, на который он указывает, больше не действителен - даже если вы восстановите биты указателя с диска. В частности, это мог быть мусор, собранный без запуска dtor.
Я думаю, это потому, что данные в контейнерах копируются с использованием подхода типа
memcpy- так что если бы у вас был указатель внутри класса, который вы хранили, вы бы копировали указатель, а не данные, на которые указывали.Когда вы сериализуете такую структуру, указываемые данные не будут сериализованы, только указатель. Когда вы восстановите данные, у вас будет указатель, который указывает на мусор.