将结构数组初始化为共享内存 [英] Initializing an array of structs into shared memory

查看:109
本文介绍了将结构数组初始化为共享内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作4个程序,这些程序创建POSIX共享内存对象(结构数组),该对象将由其他3个进程共享.基本上,该项目模拟文件.

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. Basically this project simulates files.

程序1创建对象.程序2将文件名和字符串作为参数,然后将文件名和字符串(文件内容)作为结构保存到共享内存中,该结构放入数组的可用元素中.程序#3将列出文件名.程序4将搜索给定的文件并显示其内容.

Program #1 creates the object. 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. Program #3 will list the filenames. Program #4 will search for a given file and display its contents.

我遇到的麻烦是将结构数组初始化为共享内存.我不断收到以下错误,这表明我使用的是不正确的方法初始化指针:

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!

程序1(myformat.c):

PROGRAM #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):

PROGRAM #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):

PROGRAM #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* 进行赋值,所以

There is apparently a typo, since you have no MyStruct anywhere else in the file. As rici commented, C doesn't require you to cast void* for assignment, so

    struct MyFiles *file = ptr;

足够了.

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

下标[0]已经表示一个间接寻址; file[0]的类型是struct MyFiles,所以

The subscripting [0] already denotes an indirection; the type of file[0] is struct MyFiles, so

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

是正确的.但是,rici的评论您不能假设共享内存在共享它的每个进程中都具有相同的地址也是正确的,除非您在每个mmap()中都指定了相同的地址(非NULL,与系统有关) (并检查结果是否等于该地址).即使那样,正如克里斯·多德(Chris Dodd)所写,您也永远不会为字符串分配空间.您将它们设置为指向非共享的…字符串…-对于您的项目,如果在struct MyFiles中分配一定的空间,这将是最简单的方法:

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). Even then, as Chris Dodd wrote, you never allocate space for the strings. 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
{
    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++;
…

这篇关于将结构数组初始化为共享内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆