2015-09-20 85 views
0

我正在學習使用C(linux)中的共享內存進行編程。我需要在幾個使用fork()創建的進程之間共享一些結構。不幸的是,當我試圖初始化新共享地址空間時,我在memcpy調用中遇到了一個很小的錯誤(控制檯中沒有輸出)。共享內存和memcpy問題

#include <stdio.h> 
#include <stdlib.h> 
#include <limits.h> 
#include <sys/stat.h> 
#include <sys/mman.h> 
#include <string.h> 
#include <fcntl.h> 
#include <errno.h> 

#define ROWS 10000 
#define COLS 15000 

struct mm_shared { 
    int test; 
    unsigned char matrix[ROWS][COLS]; 
}; 

int main(void) { 

    int fd; 
    if ((fd = shm_open("/mm", O_CREAT | O_RDWR, 0777)) == -1) { 
     printf(stderr, "shm_open failed! %d - %s\n", errno, strerror(errno)); 
    } 

    if (ftruncate(fd, sizeof(struct mm_shared) == -1)) { 
     printf(stderr, "ftruncate failed! %d - %s\n", errno, strerror(errno)); 
    } 

    struct mm_shared * shared; 
    if ((shared = mmap(NULL, sizeof(struct mm_shared), PROT_READ 
      | PROT_WRITE, MAP_SHARED, fd, 0)) == -1) { 
     printf("mmap failed! %d, %s\n", errno, strerror(errno)); 
    } 
    struct mm_shared * init = (struct mm_shared *) malloc(sizeof(struct mm_shared)); 

    memcpy(shared, init, sizeof(struct mm_shared)); <-- here lies the problem! 


    shm_unlink("/mm"); 
    return EXIT_SUCCESS; 
} 

在調試共享指針,調試信息(Eclipse調試器)顯示:

Failed to execute MI command: 
-data-evaluate-expression (shared)->test 
Error message from debugger back end: 
Cannot access memory at address 0x7ffff7ffc000 

我不知道這可能會有幫助。另外,我想問一下,如果我在結構體中存儲一個大矩陣的方法是正確的(它應該在堆權中分配?因爲即使矩陣本身不是指針,我也會得到一個指向結構體的指針)。

任何幫助,將不勝感激!

+0

請注意,由'malloc()'返回的數據未初始化,因此您試圖將未初始化的數據複製到共享數據上。本身不應該導致崩潰。你爲這個結構分配大約150MB,並且可能是共享內存。你當然應該驗證'malloc()'成功了,但找到失敗的桌面機器會有點令人驚訝。 –

+1

您需要編譯更多的警告。您從標題中省略了「」,「」,「」和「」。當它們被提供時,編譯器告訴你不應該使用'printf(stderr,...';大概你的意思是'fprintf(stderr,...')當你仔細琢磨那些東西,並且比較'shared ''和'-1'固定('==(void *) - 1'工作 - 'mmap()'返回一個void指針),然後編譯代碼,得到'mmap failed!22,無效參數'後跟一個核心轉儲,因爲代碼在失敗消息後繼續。 –

+1

POSIX.1 ['mmap()'](http://man7.org/linux/man-pages/man2/mmap.2.html)將返回MAP_FAILED如果發生錯誤,'(它*應該*等於'(void *) - 1'),如果發生錯誤,至少應該有一個'return EXIT_FAILURE;'此外,雖然技術上映射的「長度」不需要與「sysconf(_SC_PAGESIZE)」的下一個倍數對齊(爲了避免舍入內核或C庫中的錯誤),建議這樣做( –

回答

1

調試和審查週期的一個小時後,發現錯誤也終於要和它的這個

second argument for ftruncate seems to be evaluating to wrong value 
if (ftruncate(fd, sizeof(struct mm_shared) == -1)) { 

改爲

if (ftruncate(fd, sizeof(struct mm_shared)) == -1) { 

這裏是改變

代碼
int main(void) { 

    int fd; 
    if ((fd = shm_open("/mm", O_CREAT | O_RDWR, 0777)) == -1) { 
     fprintf(stderr, "shm_open failed! %d - %s\n", errno, strerror(errno)); // should be fprintf 
    exit(1);// possibly exit here 
    } 

    //if (ftruncate(fd, sizeof(struct mm_shared) == -1)) { 
    if (ftruncate(fd, sizeof(struct mm_shared)) == -1) { 
     fprintf(stderr, "ftruncate failed! %d - %s\n", errno, strerror(errno)); // should be fprintf 
    goto out; // remove all before leaving  
    } 

    struct mm_shared * shared; 
    if ((shared = mmap(NULL, sizeof(struct mm_shared) , PROT_READ 
      | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) { // Change -1 to MAP_FALED 
     fprintf(stderr, "mmap failed! %d, %s\n", errno, strerror(errno)); // should be fprintf and stderr 
    goto out; // remove all before leaving 
    } 
    struct mm_shared * init = (struct mm_shared *) malloc(sizeof(struct mm_shared)); 

    //memcpy(shared, init, sizeof(struct mm_shared)); //<-- here lies the problem! 
    memcpy(init, shared, sizeof(struct mm_shared)); //<-- here lies the problem! 

out: 
    shm_unlink("/mm"); 
    return EXIT_SUCCESS; 
} 
+0

天啊!我真的很抱歉這樣做!非常感謝!! :)我嚴重懷疑我是否能夠在我自己身上發現... – Lucia