共享内存的std :: string给出了分段错误(linux)

Wow*_*owy 1 c++ linux stdstring shared-memory

我目前正在尝试在Linux上的2个进程之间的共享内存中放置结构.我没有问题共享bool或int但是当尝试共享字符串时,std :: string或char我有一个分段错误错误.

现在我的代码是:

#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;
}
Run Code Online (Sandbox Code Playgroud)

在这个例子中,从2个结构共享2个bool工作得很好但是如果我尝试输入数据或从std :: string(etat,carte)读取数据,如下所示:

PrisesArray[1].etat="hello";
Run Code Online (Sandbox Code Playgroud)

它在调试中给了我一个分段错误(并且明确在发布时不起作用),我尝试使用简单的字符串和字符(甚至一个字符),它仍然给我一个分段错误.

在文本共享或在这里犯错时我错过了什么吗?

Wer*_*mus 5

它在调试中给了我一个分段错误(并且明确在发布时不起作用),我尝试使用简单的字符串和字符(甚至一个字符),它仍然给我一个分段错误.

这是因为std :: string不是POD(普通旧数据)类型.std :: string在幕后执行动态内存分配(使用new),并且在序列化它时(例如,共享内存或文件),只有指针被序列化.当反序列化(从共享内存或文件)内存到原始指针可能不再存在时,这会使反序列化的字符串无法使用.

您必须编写一个函数,专门将字符串序列化到您的共享内存,就像标准运算符std :: ostream operator >>(std :: ostream&stream,const std :: string&)的情况一样.

  • 人们还可以编写一个从共享内存中获取内存的分配器,并让字符串使用它来分配内存. (4认同)