使用mmap读取共享内存 - 分段错误

时间:2017-03-04 22:03:49

标签: c posix shared-memory

我仍然试图绕过共享内存。我想要完成的是拥有一系列豆荚。每个pod还包含一个keyValue数组。

typedef struct {
   char key[256];
   char value[256];
}keyValue;

typedef struct {
   keyValue **arr;
   int count;
}pod;

int fd;

int main(int argc, char **argv) {
   int kv_store_create(char *name) {
       return shm_open(name, O_CREAT|O_RDWR, S_IRWXU);
   }

   void kv_store_write(char *key1, char *value1) {

      static pod (*str)[28];

      ftruncate(fd, sizeof(str));

      str = (pod(*)[28])mmap(NULL, sizeof(str), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

      for (int i = 0; i < 28; i++) {
         str[i]->arr = (keyValue **)malloc(28 * sizeof(keyValue));
         for(int j = 0; j < 28; j++) {
            str[i]->arr[j] = (keyValue *)malloc(256 * sizeof(keyValue));
         }
       }

       strncpy(str[0]->arr[0]->key, key1, strlen(key1));
       strncpy(str[0]->arr[0]->value, value1, strlen(value1));
       str[0]->count = 1;
    }

   fd = kv_store_create("sharedmem");

   kv_store_write("key", "value");

所以在这一点上,我在一个pod中有一个keyValue,如果我从同一个文件中读取共享内存,我没有问题。

当我尝试从另一个进程读取时出现问题。我有以下文件

int main(int argc, char **argv) {

    typedef struct {
        char key[256];
        char value[256];
    }keyValue;

    typedef struct {
        keyValue **arr;
        int count;
    }pod;


    int fd = shm_open("sharedmem", O_RDWR, 0);
    if (fd < 0) {
        printf("Error... opening shm\n");
    }

    struct stat s;

    if (fstat(fd, &s) == -1) {
        printf("Error fstat\n");
    }

    pod (*str2)[28];

    str2 = (pod(*)[28])mmap(NULL, s.st_size, PROT_READ, MAP_SHARED, fd, 0);

    printf("%s", str2[0]->arr[0]->key); 

}

printf导致seg错误,我相信它正在尝试访问没有分配任何内存的部分内存,而printf实际上会在我的第一个文件中打印。

我正在试图弄清楚为什么要吐出一个错误,我应该采取什么途径才能在两个进程之间共享一个结构数组

谢谢!

1 个答案:

答案 0 :(得分:0)

你说的是:

  

每个pod还包含一个keyValue数组。

但事实并非如此,因为pod是:

typedef struct {
   keyValue **arr;
   int count;
}pod;

,不包含KeyValue数组。它包含指向KeyValue*数组的指针,但KeyValue对象本身既不在pod也不在arr指向的内存中。所以他们肯定不在你在两个进程之间共享的记忆中。

因此,阅读过程获得pod,其中包含指向拥有过程中地址的指针;显然,该指针在读者中完全没有意义,因为进程不共享内存,因此在另一个进程中拥有对象的地址或多或少等同于具有随机数。

简而言之,您必须确保共享内存区域实际上包含您要共享的所有对象,而不仅仅是指向它们的指针。并且由于mmap不太可能在两个进程中返回相同的地址,因此在共享内存中插入指针即使对于放置在共享内存中的对象也没有用处。