简体   繁体   English

将结构数组初始化为共享内存

[英]Initializing an array of structs into shared memory

I'm making 4 programs that creates a POSIX shared memory object, an array of structs, that will be shared by the other 3 processes. 我正在制作4个程序,这些程序创建POSIX共享内存对象(结构数组),该对象将由其他3个进程共享。 Basically this project simulates files. 基本上,该项目模拟文件。

Program #1 creates the object. 程序1创建对象。 Program #2 takes a filename and a string as arguments, then the filename and string (file contents) are saved to shared memory as a struct that is put in an available element of the array. 程序2将文件名和字符串作为参数,然后将文件名和字符串(文件内容)作为结构保存到共享内存中,该结构放入数组的可用元素中。 Program #3 will list the filenames. 程序#3将列出文件名。 Program #4 will search for a given file and display its contents. 程序4将搜索给定的文件并显示其内容。

The trouble I'm having is initialize an array of structs into shared memory. 我遇到的麻烦是将结构数组初始化为共享内存。 I keep getting the following errors, which tells me I'm using an incorrect method initializing the pointers: 我不断收到以下错误,这表明我使用的是不正确的方法初始化指针:

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

I've searched this subject and found a few similar problems, but nothing really relative to my issue. 我搜索了这个主题,发现了一些类似的问题,但与我的问题无关。

So, how do you properly initializing an array of structs into shared memory? 那么,如何正确地将结构数组初始化为共享内存?

Based on my research, I have coded the following. 根据我的研究,我编写了以下代码。 Thanks! 谢谢!

PROGRAM #1 (myformat.c): 程序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;

}

PROGRAM #2 (mycreate.c): 程式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;
}

PROGRAM #3 (myls.c): 计划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; 

There is apparently a typo, since you have no MyStruct anywhere else in the file. 显然有错别字,因为文件中其他任何地方都没有MyStruct As rici commented, C doesn't require you to cast void* for assignment, so 正如rici所评论的那样, C并不需要您为指定赋值void*

    struct MyFiles *file = ptr;

suffices. 就足够了。

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

The subscripting [0] already denotes an indirection; 下标[0]已经表示间接; the type of file[0] is struct MyFiles , so file[0]的类型是struct MyFiles ,所以

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

would be correct. 是正确的。 However, rici's comment you cannot assume that shared memory will have the same address in every process which shares it is also right, unless you specify the same address (not NULL, system dependent) in every mmap() (and check that the result equals that address). 但是,rici的评论不能假设共享内存在共享它的每个进程中都具有相同的地址,这也是正确的,除非您在每个mmap()指定相同的地址(非NULL,取决于系统mmap() (并检查结果是否等于该地址)。 Even then, as Chris Dodd wrote, you never allocate space for the strings. 即使那样,正如克里斯·多德(Chris Dodd)所写, 您也永远不会为字符串分配空间。 You set them to point at non-shared … strings … - For your project, it would be the easiest way if you allocate a certain amount of space within struct MyFiles : 您将它们设置为指向非共享的…字符串… -对于您的项目,如果在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