将结构数组初始化为共享内存 [英] Initializing an array of structs into shared memory
问题描述
我正在制作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屋!