簡體   English   中英

將結構數組初始化為共享內存

[英]Initializing an array of structs into shared memory

我正在制作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;
}
  struct MyFiles* file = (struct MyStruct*)ptr; 

顯然有錯別字,因為文件中其他任何地方都沒有MyStruct 正如rici所評論的那樣, C並不需要您為指定賦值void*

    struct MyFiles *file = ptr;

就足夠了。

  file[0]->fileName = "\\0"; file[0]->fileContents = "\\0"; 

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

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

是正確的。 但是,rici的評論不能假設共享內存在共享它的每個進程中都具有相同的地址,這也是正確的,除非您在每個mmap()指定相同的地址(非NULL,取決於系統mmap() (並檢查結果是否等於該地址)。 即使那樣,正如克里斯·多德(Chris Dodd)所寫, 您也永遠不會為字符串分配空間。 您將它們設置為指向非共享的…字符串… -對於您的項目,如果在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++;
…

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM