2017-03-04 116 views
0

我仍然試圖圍繞共享內存打包頭。我試圖完成的是有一個豆莢數組。每個窗格還將包含一個keyValue數組。使用mmap從共享內存中讀取 - 分割錯誤

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的是造成賽格故障,我相信它正試圖訪問具有分配沒有什麼記憶的一部分,而printf的實際上在我的第一個文件打印。

我試圖找出爲什麼吐出一個錯誤,我應該採取什麼樣的路線,能夠分享兩個進程之間的結構數組

謝謝!

+0

[不是原因]'strncpy(str [0] - > arr [0] - > key,key1,strlen(key1));'*完全*錯誤。 – wildplasser

回答

0

你說的是:

每個吊艙也將包含的keyValue數組。

但事實並非如此,因爲莢是:

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

不包含的KeyValue陣列。它包含一個指向KeyValue*數組的指針,但KeyValue對象本身既不在pod中,也不在arr指向的內存中。所以他們肯定不在你在這兩個進程之間共享的內存中。

因此,讀取過程得到pod,其中包含指向地址的指針,該指針位於擁有進程;顯然,在讀者中該指針是完全沒有意義的,因爲進程不共享內存,所以在另一個進程中擁有一個對象的地址或多或少等同於擁有一個隨機數。

簡而言之,您必須確保共享內存區域實際上包含您要共享的所有對象,而不僅僅是指向它們的指針。由於mmap不可能在兩個進程中返回相同的地址,因此將共享內存中的指針插入到共享內存中的對象中也是沒有用的。

+0

真棒,我已經玩了一會兒,並設法分享一個單獨的包含一個keyValue與另一個進程typedef struct {keyValue arr; }。 我想我會需要typedef結構{keyValue * arr; }爲一個keyValue數組,對嗎? –

+0

@Bibik:'KeyValue'的一個數組是'KeyValue []';它會*衰減*到一個'KeyValue *',但是你不應該混淆這兩者。另外,如果你輸入一個指針類型,你幾乎肯定會最終迷惑自己和任何讀你代碼的人。 * *是尖尖的,應該是可見的;否則你最終會刺痛自己。更復雜的是試圖創建一個動態調整大小的數組對象,因爲C數組總是固定大小(即使它們是VLA)。在這種情況下,你需要一個'KeyValue *',但是要記住它和數組不是一回事。 – rici

+0

@Bibik:順便說一下,'count'的含義是什麼?你真的打算共享數據結構是28個'KeyValue'的28個數組的數組,總共784對? – rici