#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;
}
我从共享内存教程中获取了代码。它一直有效,直到我定义了struct LOCK并尝试将LOCK而不是char *写入共享内存。
有人可以帮我解决导致分段错误的问题吗?
答案 0 :(得分:11)
您将vector
和string
放入共享内存。这两个类都分配自己的内存,这些内存将在任何进程生成分配的地址空间内分配,并在从其他进程访问时产生段错误。您可以尝试指定分配器来使用该共享内存,但由于在C ++ 03中假定分配器是无状态的,我不确定它是否可行。
考虑一下Boost.Interprocess如何做到这一点。
答案 1 :(得分:2)
你有很多问题。显而易见的是,你没有构造你的对象。以不透明的形式,您目前正在做:
class Foo;
Foo * p = get_memory();
p->bar = 5; // ouch!
至少应该做什么:
void * addr = get_memory(sizeof(Foo));
Foo * p = ::new (addr) Foo;
// do work
p->~Foo(); // done
(根据您的情况,只需将Foo
替换为LOCK
。)
但是,它变得更加复杂:vector
和string
本身需要动态分配。该内存必须与LOCK
位于同一地址空间。所以解决这个问题的标准方法是编写自己的分配器并传递:
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;
};
最后,你必须编写一个符合条件的allocator类,它将内存放在与LOCK
对象最终到达的地址空间相同的地址空间中:
template <typename T>
class shared_allocator { /* write this! */ }
typedef Lock<shared_allocator> LOCK;
答案 2 :(得分:1)
我知道很久以前。但我正在寻找关于共享内存的方法(记住),这个帖子很有趣。
我要求的两分钱:
共享内存ID == file_handle from open(...);
那么......你如何正确地序列化然后将std :: string甚至std :: vector读写到文件中?你真的从文件中“扩展/缩小”std :: string或std :: vector吗?
谢谢:)