我正在制作 4 个程序来创建一个 POSIX 共享内存对象,一个结构数组,它将被其他 3 个进程共享。基本上这个项目模拟文件。
程序 #1 创建对象。程序 #2 将文件名和字符串作为参数,然后将文件名和字符串(文件内容)作为结构保存到共享内存中,并将其放入数组的可用元素中。程序#3 将列出文件名。程序 #4 将搜索给定文件并显示其内容。
我遇到的问题是将一个结构数组初始化到共享内存中。我不断收到以下错误,这告诉我我使用了不正确的方法来初始化指针:
myformat.c:36: 警告:从不兼容的指针类型初始化
我搜索了这个主题并发现了一些类似的问题,但与我的问题无关。
那么,如何正确地将结构数组初始化到共享内存中?
根据我的研究,我编写了以下代码。谢谢!
程序#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 的评论 你不能假设共享内存在共享它的每个进程中都具有相同的地址 也是正确的,除非你在每个 中指定相同的地址(不是 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++;
…
关于c - 将结构数组初始化为共享内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27350679/