Почему структуры, хранящие простые указатели на внутреннюю память, не могут храниться в контейнерах 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
- так что если бы у вас был указатель внутри класса, который вы хранили, вы бы копировали указатель, а не данные, на которые указывали.Когда вы сериализуете такую структуру, указываемые данные не будут сериализованы, только указатель. Когда вы восстановите данные, у вас будет указатель, который указывает на мусор.