shared memory of std::string give segmentation fault (linux)

冷暖自知 提交于 2019-12-11 10:47:25

问题


I am currently trying the put structures in a shared memory between 2 process on linux. I have no problem sharing bool or int but when trying to share a string, std::string or char i have a segmentation fault error.

Right now my code is :

#include <iostream>
#include <sys/types.h> //shmat
#include <sys/shm.h>
#include <sys/stat.h> //open
#include <fcntl.h>
#include <unistd.h> //close

using namespace std;

struct Prises{

int numero;
int transactionId;
bool reservation;
bool charge;
bool disponibilite;
bool defaut;
bool verrouillage;
bool trappe;
int LEDverte;
int LEDrouge;
std::string carte;
std::string etat;

};

int main()
{
const char *keyFile = "/tmp/key.dat";
/* Make sure the file exists. */
int descriptor = open(keyFile, O_CREAT | O_RDWR, S_IRWXU);

/* Only wanted to make sure that the file exists. */
close(descriptor);

/* Generate memory key. */
key_t sharedKey = ftok(keyFile, 1);

/* Get the shared memory segment id. Note we include
   the permissions. */
int sharedSpaceId = shmget(sharedKey, 2*sizeof(Prises),
    IPC_CREAT | S_IRUSR | S_IWUSR);

/* Attach the shared memory segment. */
Prises *PrisesArray = (Prises *) shmat(sharedSpaceId, NULL, 0);

PrisesArray[1].defaut=true;
PrisesArray[2].defaut=false;

int ok;
std::cin>>ok;
return 0;
}

In this example sharing the 2 bool from the 2 structures is working well but if i try to input a data or read a data from the std::string (etat, carte) like this :

PrisesArray[1].etat="hello";

It gives me a segmentation fault in debug (and clear don't work in release), i tried with simple string and char (even one char) and it still gives me a segmentation fault.

Am i missing something when it comes to text sharing or making a mistake here ?


回答1:


It gives me a segmentation fault in debug (and clear don't work in release), i tried with simple string and char (even one char) and it still gives me a segmentation fault.

This is because std::string is not a POD (Plain Old Data) type. std::string performs dynamic memory allocation (using new) behind the scenes, and when serializing it (e.g to shared memory or file), only the pointers are serialized. When deserializing it (from shared memory or file) memory to the original pointers are likely to not exist anymore, and this renders the deserialized string unusable.

You would have to write a function that specifically serializes the string explicitly to your shared memory, as is the case with the standard operator std::ostream operator >>(std::ostream& stream, const std::string&)




回答2:


You have to share the data associated with the std::string, i.e.

//server part:

struct ShmData{
`...`
char chAux[1024];
};

int main()
{
...
shared_memory_object shm (create_only, "MyMem", read_write);
shm.truncate(offset_t(sizeof(ShmData)) );
mapped_region region(shm, read_write);
ShmData *shmData = (ShmData*)(region.get_address());
...
std::string str( "some stuff over the server" );
...
strcpy( shmData->chAux, str.c_str() );
...
}
//on client, the same struct and:
int main()
{
shared_memory_object shm (open_only, "MyMem", read_write); 
mapped_region region(shm, read_write);
ShmData *shmData = (ShmData*)(region.get_address());
std::string strLocal(shmData->chAux); //assign to a local string the  shared data
std::cout << "show strLocal\n";
std::cout << strLocal << std::endl;
....
}


来源:https://stackoverflow.com/questions/32581057/shared-memory-of-stdstring-give-segmentation-fault-linux

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!