2014-12-08 65 views
1

我正在創建4個程序,該程序創建一個POSIX共享內存對象,這是一個結構數組,它將由其他3個進程共享。基本上這個項目模擬文件。將結構數組初始化爲共享內存

程序#1創建對象。程序#2將一個文件名和一個字符串作爲參數,然後將文件名和字符串(文件內容)作爲一個結構保存到共享內存中,該結構放入數組的可用元素中。程序#3將列出文件名。程序#4將搜索給定的文件並顯示其內容。

我遇到的麻煩是將結構數組初始化爲共享內存。我不斷收到以下錯誤,告訴我,我使用的是不正確的方法初始化指針:

myformat.c:36: warning: initialization from incompatible pointer type

我搜索這個問題,並發現了一些類似的問題,但沒有真正相對於我的問題。

那麼,你如何正確地初始化一個結構數組到共享內存?

基於我的研究,我編碼了以下內容。謝謝!

節目#1(myformat.c):

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <fcntl.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 

struct MyFiles 
{  
    char *fileName;  
    char *fileContents;  
}; 

int main()  
{  
    /* the size of shared memory object */  
    int size = sizeof(struct MyFiles)* 20; 

    /* name of the shared memory object */  
    const char *name = "/PROJ4_SHARED_MEM";  

    /* shared memory file descriptor */  
    int shm_fd; 

    /* pointer to shared memory obect */  
    void *ptr; 

    /* create the shared memory object */  
    shm_fd = shm_open(name, O_CREAT | O_RDRW, 0666);  

    /* configure the size of the shared memory object */  
    ftruncate(shm_fd, size);  

    /* memory map the shared memory object */  
    ptr = mmap(0, size, PROT_WRITE, MAP_SHARED, shm_fd, 0);  
    struct MyFiles* file = (struct MyStruct*)ptr;   

    /* save struct array to the shared memory object. Initialize first element. */  
    file[0]->fileName = "\0";  
    file[0]->fileContents = "\0";  

    return 0; 

} 

節目#2(mycreate.c):

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <fcntl.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 

struct MyFiles 
{ 
    char *fileName; 
    char *fileContents; 
}; 

int main() 
{ 
    char *file_name = argv(0); 
    char *file_contents = argv(1); 

    /* the size of shared memory object */ 
    int size = sizeof(struct MyFiles)* 20; 

    /* name of the shared memory object */ 
    const char *name = "/PROJ4_SHARED_MEM"; 

    /* shared memory file descriptor */ 
    int shm_fd; 

    /* pointer to shared memory object */ 
    void *ptr; 

    /* open the shared memory object */ 
    shm_fd = shm_open(name, O_RDRW, 0666); 

    /* memory map the shared memory object */ 
    ptr = mmap(0, size, PROT_WRITE, MAP_SHARED, shm_fd, 0); 
    struct MyFiles* file = (struct MyStruct*)ptr; 

    /*write to first available array slot in shared memory object. Initialize next. */ 
    for (int i = 0; i < 20; i++) 
    { 
     if (file[i].fileName == "\0") 
     { 
      sprintf(file[i]->fileName,"%s",file_name); 
      sprintf(file[i]->fileContents,"%s",file_contents); 
      file[i + 1]->fileName = "\0"; 
      file[i + 1]->fileContents = "\0"; 
      break; 
     } 
     else if (i == 19) 
     { 
      prinf("ERROR: The Shared Memory Object is full.\n\n"); 
      shm unlink(name); 
      exit(1); 
     } 
    } 

    /* remove the shared memory object */ 
    shm unlink(name); 

    return 0; 
} 

節目#3(myls.c):

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <fcntl.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 

struct MyFiles 
{ 
    char *fileName; 
    char *fileContents; 
}; 

int main() 
{ 
    char *file_name = argv(0); 
    char *file_contents = argv(1); 

    int counter = 0; 

    /* the size of shared memory object */ 
    int size = sizeof(struct MyFiles)* 20; 

    /* name of the shared memory object */ 
    const char *name = "/PROJ4_SHARED_MEM"; 

    /* shared memory file descriptor */ 
    int shm_fd; 

    /* pointer to shared memory object */ 
    void *ptr; 

    /* open the shared memory object */ 
    shm_fd = shm_open(name, O_RDONLY, 0666); 

    /* memory map the shared memory object */ 
    ptr = mmap(0, size, PROT_READ, MAP_SHARED, shm_fd, 0); 
    struct MyFiles* file = (struct MyStruct*)ptr; 

    if (file[0].fileName == "\0") 
    { 
      prinf("ERROR: There are no saved files in the shared memory object.\n\n"); 
      exit(1); 
    } 

    /*List all filenames */ 
    while (file[counter].fileName != "\0";) 
    { 
     prinf("%s \n", file[counter]->fileName); 
     counter++; 
    } 

    /* remove the shared memory object */ 
    shm unlink(name); 

    return 0; 
} 
+1

你分配'包含指針的MyFiles'對象字符串,但是你永遠不會爲字符串分配空間。您將它們設置爲指向非共享常量字符串(字符串文字),然後嘗試修改這些未定義行爲的字符串。您應該首先了解如何在單個程序中管理字符串,而不涉及共享內存。 – 2014-12-08 03:17:18

+0

@ChrisDodd所以我應該把項目放入一個結構中,分配內存,然後使用指針將其放置在共享內存中?它會提前分配一堆內存嗎?說這樣的:'int size = 4096;'? – LazyBear 2014-12-08 03:23:34

+0

實際的錯誤信息是這行(第36行)的結果:struct MyFiles * file =(struct MyStruct *)ptr;'它從(結構體)'struct MyStruct *'初始化'struct MyFiles *'。 C不要求你施放'void *',但是如果你打算這麼做,你必須投射正確的指針類型。 – rici 2014-12-08 03:35:36

回答

0
struct MyFiles* file = (struct MyStruct*)ptr; 

顯然有一個錯字,因爲您沒有MyStruct文件中的任何其他位置。作爲RICI評論,C不要求你投void*進行分配,所以

struct MyFiles *file = ptr; 

就足夠了。

​​

的下標[0]已經表示間接;的file[0]類型爲struct MyFiles,所以

file[0].fileName = "\0";  
    file[0].fileContents = "\0";  

是正確的。然而,rici的評論你不能假定共享內存在每個共享它的進程中都有相同的地址也是對的,除非你在每個mmap()中指定了相同的地址(不是NULL,取決於系統)(並檢查結果是否等於該地址)。即便如此,正如克里斯多德所寫,你永遠不會爲字符串分配空間。您可以設置在這些非共享...串點... - 爲您的項目,這將是最簡單的方法,如果您在struct MyFiles分配一定數量的空間:

struct MyFiles 
{ 
    char fileName[12]; 
    char fileContents[500]; 
}; 
… 
    /* Initialize first element. */ 
    // We can well omit this, since newly allocated bytes of a 
    // shared memory object are automatically initialized to 0. 
    file[0].fileName[0] = '\0'; 
    file[0].fileContents[0] = '\0'; 
… 
    /* write to first available array slot in shared memory object */ 
    for (int i = 0; i < 20; i++) 
    { 
     if (file[i].fileName[0] == '\0') 
     { 
      sprintf(file[i].fileName, "%11s", file_name); 
      sprintf(file[i].fileContents, "%499s", file_contents); 
… 
    /* List all filenames. */ 
    while (file[counter].fileName[0] != '\0') 
    { 
     puts(file[counter]->fileName); 
     counter++; 
…