segmentation generado error dumped c++ linux segmentation-fault shared-memory

c++ - generado - error segmentation fault c



Un sencillo programa de memoria compartida de C++ escrito en Linux: falla de segmentación (3)

#include <stdio.h> #include <sys/shm.h> #include <sys/stat.h> #include <string> #include <vector> #include <iostream> using namespace std; struct LOCK { string name; string type; vector <string> pids; }; int main () { int segment_id; LOCK* shared_memory; struct shmid_ds shmbuffer; int segment_size; const int shared_segment_size = 0x6400; /* Allocate a shared memory segment. */ segment_id = shmget (IPC_PRIVATE, shared_segment_size, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR); /* Attach the shared memory segment. */ shared_memory = (LOCK*) shmat (segment_id, 0, 0); printf ("shared memory attached at address %p/n", shared_memory); /* Determine the segment''s size. */ shmctl (segment_id, IPC_STAT, &shmbuffer); segment_size = shmbuffer.shm_segsz; printf ("segment size: %d/n", segment_size); /* Write a string to the shared memory segment. */ //sprintf (shared_memory, "Hello, world."); shared_memory -> name = "task 1"; shared_memory -> type = "read"; (shared_memory -> pids).push_back("12345"); (shared_memory -> pids).push_back("67890"); /* Detach the shared memory segment. */ shmdt (shared_memory); /* Reattach the shared memory segment, at a different address. */ shared_memory = (LOCK*) shmat (segment_id, (void*) 0x5000000, 0); printf ("shared memory reattached at address %p/n", shared_memory); /* Print out the string from shared memory. */ //printf ("%s/n", shared_memory -> name); cout << "Name of the shared memory: " + shared_memory -> name << endl; /* Detach the shared memory segment. */ shmdt (shared_memory); /* Deallocate the shared memory segment. */ shmctl (segment_id, IPC_RMID, 0); return 0; }

Obtuve el código de un tutorial sobre memoria compartida. Funcionó hasta que definí struct LOCK y traté de escribir LOCKs en lugar de char * en la memoria compartida.

¿Podría alguien ayudarme a resolver el problema aquí que causa la falla de segmentación?


Coloca vector y string en la memoria compartida. Ambas clases asignan memoria propia, que se asignará dentro del espacio de direcciones de cualquier proceso que genere la asignación, y producirá una segfault cuando se acceda desde el otro proceso. Podría intentar especificar asignadores para usar esa memoria compartida, pero dado que en C ++ 03 se supone que las asignaciones son sin estado, no estoy seguro de si será posible.

Considera ver cómo lo hace Boost.Interprocess.


Usted tiene una serie de problemas. El más obvio es que no construyes tu objeto. En forma opaca, actualmente estás haciendo:

class Foo; Foo * p = get_memory(); p->bar = 5; // ouch!

Lo que deberías estar haciendo, al menos:

void * addr = get_memory(sizeof(Foo)); Foo * p = ::new (addr) Foo; // do work p->~Foo(); // done

(Simplemente reemplace a Foo por LOCK para su situación).

Sin embargo, se vuelve más complicado: el vector y la string requieren asignaciones dinámicas. Esa memoria debe vivir en el mismo espacio de direcciones que tu LOCK . Entonces, la forma estándar de resolver esto es escribir su propio asignador y pasarlo:

template <template <typename> class Alloc> struct Lock { typedef std::basic_string<char, std::char_traits<char>, Alloc<char>> shared_string; shared_string name; shared_string type; std::vector<shared_string, Alloc<shared_string>> pids; };

Finalmente, debe escribir una clase de asignador conforme que coloque la memoria en el mismo espacio de direcciones que aquel en el que su objeto LOCK irá en última instancia:

template <typename T> class shared_allocator { /* write this! */ } typedef Lock<shared_allocator> LOCK;


Sé que fue hace mucho tiempo. Pero estaba buscando cómo hacerlo (recordar) sobre la memoria compartida y este hilo es interesante.

Mis dos centavos al demandante:

  • Tenga en cuenta que leer y escribir en SharedMemory es exactamente como leer y escribir en un FileSystem.
  • Shared Memory ID == file_handle from open (...);

    Entonces ... ¿Cómo serializar CORRECTAMENTE y luego leer-escribir std :: string o incluso std :: vector en un ARCHIVO? ¿Realmente ''expandes / contraes'' un std :: string o std :: vector desde un ARCHIVO?

Gracias :)