2011-06-18 4 views
1

J'ai utilisé boost :: interprocess :: managed_ (windows_) shared_memory :: construct pour construire un vecteur interprocess contenant sa propre classe, qui a une variable membre de type std :: string et une autre sorte de type std :: vecteur,:boost :: interprocessus - std :: chaîne vs. std :: vecteur

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 */ 
} 

Je viens de faire cela pour le test, je ne devrait std :: string ni std :: vecteur de travailler, mais, si Je l'ai lu d'un autre processus, std :: string fonctionne, il contient la chaîne que j'ai assignée. Cela m'a vraiment surpris. Le vecteur std :: de l'autre côté ne fonctionne que partiellement, la valeur renvoyée par size() est correcte, mais le programme se bloque si je veux accéder à un itérateur ou en utilisant operator []. Alors, ma question est la suivante: pourquoi est-ce ainsi? Je veux dire, je ne lis jamais réellement les implémentations STL du SDK de Visual Studio, mais n'est-ce pas std :: string juste un vecteur std :: avec des fonctions supplémentaires adaptées aux chaînes? N'utilisent-ils pas tous les deux std :: allocator - ce qui voudrait dire, que std :: string et std :: vector ne fonctionneraient pas dans la mémoire partagée? Googling pour cela ne résulte pas vraiment en quelque chose mais boost :: interprocess :: vector, et ce n'est pas ce que j'ai cherché. PS: Si j'ai fait une faute de frappe dans le code ci-dessus, s'il vous plaît pardonnez-moi, je viens de l'écrire en ce moment dans cet éditeur de pages et d'une manière un peu trop utilisé pour la saisie semi-automatique de mon IDE ^^

Répondre

6

std::string fonctionne parce que votre implémentation de bibliothèque standard utilise l'optimisation de petite chaîne (SSO). Cela signifie que la valeur de la chaîne "something" est copiée dans l'objet chaîne lui-même, sans aucune allocation de mémoire dynamique. Par conséquent, vous pouvez le lire à partir de l'autre processus. Pour les chaînes plus longues (essayez 30 caractères) cela ne fonctionnera pas.

std::vector ne fonctionne pas car il n'est pas autorisé à utiliser SSO par défaut. Il alloue la mémoire dans l'espace d'adressage du premier processus, mais cette mémoire n'est pas accessible par l'autre processus. Le .size() fonctionne parce qu'il est stocké à l'intérieur le vecteur lui-même, en tant que membre.

P.S. il existe de nombreuses différences entre string et vector. Le plus important, et le moins mentionné, est que string is not a container from standard's point of view.

+0

Exactement. Cela ne fonctionnera donc pas pour des chaînes plus longues. Check it: _) – sehe

+0

merci beaucoup ^^ et oui j'ai oublié de mentionner que std :: vector se comporte exactement comme je m'y attendais ^^ Mais je n'ai jamais rien entendu de SSO avant ^^ – Andy

Questions connexes