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

时间:2014-12-08 02:52:33

标签: c linux struct posix shared-memory

我制作4个程序来创建一个POSIX共享内存对象,一个结构数组,将由其他3个进程共享。基本上这个项目模拟文件。

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

我遇到的麻烦是将一个结构数组初始化为共享内存。我一直收到以下错误,这告诉我我正在使用不正确的方法来初始化指针:

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

我搜索了这个主题,发现了一些类似的问题,但没有真正与我的问题相关。

那么,如何正确地将结构数组初始化为共享内存?

根据我的研究,我编写了以下内容。谢谢!

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;

}

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

#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 个答案:

答案 0 :(得分: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的评论你不能假设共享内存在每个共享它的进程中具有相同的地址也是正确的,除非你在每个{{1}中指定相同的地址(不是NULL,系统相关) (并检查结果是否等于该地址)。即便如此,正如克里斯·多德写的那样,你永远不会为琴弦分配空间。您将它们设置为指向非共享...字符串...... - 对于您的项目,如果您在mmap()中分配一定数量的空间,这将是最简单的方法:

struct MyFiles
相关问题