boost :: interprocess - std :: string против std :: vector - PullRequest
1 голос
/ 18 июня 2011

Я использовал boost :: interprocess :: managed_ (windows_) shared_memory :: construct для создания вектора межпроцессного процесса, содержащего собственный класс, который имеет переменную-член типа std :: string и другую типа std :: vector, поэтому:

class myclass
{
    public:
        myclass()
        {

        }

        std::string _mystring;
        std::vector < int > _myintvector;
};

template < class _type >
struct typedefs
{
    typedef boost::interprocess::managed_windows_shared_memory     _memory;
    typedef _memory::segment_manager                               _manager;
    typedef boost::interprocess::allocator < _type, _manager >     _allocator;
    typedef boost::interprocess::vector < _type, _allocator >      _vector;
};

typedef typedefs < myclass > tdmyclass;

int main ()
{
    using namespace boost::interprocess;

    managed_windows_shared_memory mem ( open_or_create, "mysharedmemory", 65536 );
    tdmyclass::_vector * vec = mem.construct < tdmyclass::_vector > ( "mysharedvector" ) ( mem.get_segment_manager() );
    myclass mytemp;

    mytemp._mystring = "something";
    mytemp._myintvector.push_back ( 100 );
    mytemp._myintvector.push_back ( 200 );

    vec->push_back ( mytemp );

    /* waiting for the memory to be read is not what this is about, 
    so just imagine the programm stops here until everything we want to do is done */
}

Я только что сделал это для тестирования, я не ожидал, что ни std :: string, ни std :: vector не будут работать, но если я прочитал это из другого процесса, std :: string действительно работает, он содержит строку, которую я назначил.Это действительно удивило меня.Std :: vector с другой стороны работает только частично, значение, возвращаемое функцией size (), является правильным, но программа завершается сбоем, если я хочу получить доступ к итератору или с помощью оператора [].

Итак, мойвопрос, почему это так?Я имею в виду, я никогда не читал реализации STL SDK Visual Studio, но разве std :: string не является просто std :: vector с дополнительными функциями, подходящими для строк?Разве они оба не используют std :: allocator - что означало бы, что ОБА std :: string и std :: vector не будут работать в разделяемой памяти?

Поиск в Google для этого на самом деле ни к чему не приводитно boost :: interprocess :: vector, и это не то, что я искал.Поэтому я надеюсь, что кто-то может дать мне некоторые подробности о том, что происходит ^^

PS: Если я сделал опечатку в приведенном выше коде, пожалуйста, простите меня, я просто написал это прямо сейчас в этом редакторе страниц, и я вродеслишком часто используется для автозаполнения моей IDE ^^

1 Ответ

7 голосов
/ 18 июня 2011

std::string работает, потому что ваша стандартная реализация библиотеки использует оптимизацию маленьких строк (SSO).Это означает, что значение строки "something" копируется в сам объект строки без каких-либо динамических выделений памяти.Следовательно, вы можете прочитать это из другого процесса.Для более длинных строк (попробуйте 30 символов) это не сработает.

std::vector не сработает, потому что по стандарту не разрешено использовать SSO.Он выделяет память в адресном пространстве первого процесса, но этот процесс недоступен для другого процесса..size() работает, потому что он хранится внутри самого вектора как члена.

PS Существует много различий между string и vector.Наиболее важным и наименее упомянутым является то, что string является , а не контейнером с точки зрения стандарта .

...