c++pointersvectorstxxl

Why cannot structs storing plain pointers to internal memory be stored in stxxl containers?


In the stxxl FAQ, I found this:

Parameterizing STXXL Containers

STXXL container types like stxxl::vector can be parameterized only with a value type that is a POD (i.e. no virtual functions, no user-defined copy assignment/destructor, etc.) and does not contain references (including pointers) to internal memory. Usually, "complex" data types do not satisfy this requirements.

This is why stxxl::vector<std::vector<T> > and stxxl::vector<stxxl::vector<T> > are invalid. If appropriate, use std::vector<stxxl::vector<T> >, or emulate a two-dimensional array by doing index calculation.

The inability to use stxxl::vector<std::vector<T> > makes perfects sense, as stxxl containers do not call constructors or destructors of the contained elements upon container resize. But what about storing a struct like this:

struct S {
    int* a;
}

If I do guarantee that the object pointed by a is valid as long as the stxxl::vector<S> instance exists, what's a problem in storing this struct into a stxxl::vector<S>? If a particular instance of S has to be moved to disk, then the value of the a pointer is written on disk. Later on, the pointer value is restored and I can use it. Obviously the pointer value is machine-dependent and instance-dependent too, but is this a matter even if I take care of the lifetime of the pointed object? I am not sending a serialized object via a socket, and I am not storing a serialized object in a database for later use.

Am I missing something?

EDIT: someone reminded me that stxxl does not copy the pointee, and therefore I may get a pointer-to-garbage when I retrieve an instance of struct S later on. I know that. I'll guarantee that the pointee is valid throughout the full lifetime of the program.


Solution

  • (including pointers) to internal memory

    This means a pointer to a member of the struct, or otherwise a pointer into the memory that the container manages. E.g. you have

    struct Foo {
         int *a;
         int b;
    };
    
    Foo f;
    f.a = &f.b
    

    Since f.a now points to a member of the struct, and that struct could be copied around, the pointer can be invalid. Similar, if the pointer points to any other struct Foo managed by the container- which could be moved around too.

    If you just have a pointer, and manage what it points to, you should be fine.