在C中向POSIX共享内存对象添加一维数组
我正在开发一个基于POSIX的程序,它在两个或多个进程之间共享一个内存对象,也就是服务器-客户机程序 我对程序的服务器端有一些问题。我知道如何使用在C中向POSIX共享内存对象添加一维数组,c,posix,shared-memory,C,Posix,Shared Memory,我正在开发一个基于POSIX的程序,它在两个或多个进程之间共享一个内存对象,也就是服务器-客户机程序 我对程序的服务器端有一些问题。我知道如何使用mmap()映射内存,以及如何在两个不同的进程/程序之间使用对象。但是,在向共享内存对象添加整数数组时,我遇到了一个问题 我可以使用sprintf()将内容打印到共享内存对象,然后通过简单地说ptr+=strlen(whatstringiamworkingwith)来增加(重新分配)共享内存对象的空间 但是,当对象包含C中的整数数组时,我不知道如何将内
mmap()
映射内存,以及如何在两个不同的进程/程序之间使用对象。但是,在向共享内存对象添加整数数组时,我遇到了一个问题
我可以使用sprintf()
将内容打印到共享内存对象,然后通过简单地说ptr+=strlen(whatstringiamworkingwith)来增加(重新分配)共享内存对象的空间代码>
但是,当对象包含C中的整数数组时,我不知道如何将内存重新分配给该对象。下面是我的程序:
#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
int *calcCollatz(int n) {
int solution;
int *collatzSeq = malloc(sizeof(int));
int j = 0;
while (n != 1) {
if (n % 2 == 0) {
solution = n / 2;
n = solution;
collatzSeq[j] = n;
j++;
return collatzSeq;
} else {
solution = (3 * n) + 1;
n = solution;
collatzSeq[j] = n;
j++;
return collatzSeq;
}
}
}
int main(int argc, char *argv[])
{
const int SIZE = 4096; //size in bytes of Shared Memory Object
const char *sharedObj = "Shm"; //name of the Shared memory Object
int shm_fd; //Shared memory file descriptor
void *ptrShm; //Pointer to shared memory object
shm_fd = shm_open(sharedObj, O_CREAT | O_RDWR, 0666); //Create Shared Memory Object
ftruncate(shm_fd, SIZE); //configure the size of the shared memory object
//Map the shared memory object in the space of the process
ptrShm = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (ptrShm == MAP_FAILED) {
printf("Map Failed\n");
return -1;
}
sprintf(ptrShm, argv[1]);
ptrShm += strlen(argv[1]);
sprintf(ptrShm, calcCollatz(atoi(argv[1])));
ptrShm += sizeof(calcCollatz(atoi(argv[1])));
printf("Writing the sequence to a shared memory object!\n");
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int*calcCollatz(int n){
int解;
int*collatzSeq=malloc(sizeof(int));
int j=0;
而(n!=1){
如果(n%2==0){
溶液=n/2;
n=溶液;
collatzSeq[j]=n;
j++;
返回序列;
}否则{
溶液=(3*n)+1;
n=溶液;
collatzSeq[j]=n;
j++;
返回序列;
}
}
}
int main(int argc,char*argv[])
{
const int SIZE=4096;//共享内存对象的大小(字节)
const char*sharedObj=“Shm”//共享内存对象的名称
int shm_fd;//共享内存文件描述符
void*ptrShm;//指向共享内存对象的指针
shm_fd=shm_open(sharedObj,O_Create | O_RDWR,0666);//创建共享内存对象
ftruncate(shm_fd,SIZE);//配置共享内存对象的大小
//在进程空间中映射共享内存对象
ptrShm=mmap(0,大小,保护写入,映射共享,shm\u fd,0);
如果(ptrShm==MAP_失败){
printf(“映射失败\n”);
返回-1;
}
sprintf(ptrShm,argv[1]);
ptrShm+=strlen(argv[1]);
sprintf(ptrShm,calcCollatz(atoi(argv[1]));
ptrShm+=sizeof(calcCollatz(atoi(argv[1]));
printf(“将序列写入共享内存对象!\n”);
返回0;
}
我的思路是否正确?您的代码中存在一些错误和问题
ptr+=strlen(与什么相关)代码>正在推进指针,而不是
重新分配内存
做sprintf(ptrShm,argv[1])如果我执行你的程序,代码>是危险的
如下所示:/yourprogram%s
,则您将有未定义的行为作为%s
说明符将存在,但指向满足说明符要求的char*
的指针不存在
丢失的切勿将用户填写的变量作为printf
&
这样做:
sprintf(ptrShm, "%s", argv[1]);
fprintf(stderr, "Map failed: %s\n", strerrno(errno));
// or
perror("Map failed");
Sames这样说:sprintf(ptrShm,calcCollatz(atoi(argv[1]))代码>
如果您没有检查是否有足够的命令行参数,您应该
在程序开始时添加以下内容:
if(argc != 2)
{
fprintf(stderr, "usage: %s data\n", argv[0]);
return 1;
}
错误消息应该打印到stderr
,而不是
printf(“映射失败\n”)代码>您应该执行以下操作:
fprintf(stderr, "Map failed\n");
但这不是很有用,您还应该打印errno
像这样:
sprintf(ptrShm, "%s", argv[1]);
fprintf(stderr, "Map failed: %s\n", strerrno(errno));
// or
perror("Map failed");
您没有检查返回值shm\u open
退出代码是有符号的8位值,因此执行return-1
相当于
返回255
如shm_open
手册页所述:
文轩酒店
共享内存对象应以/somename
的形式标识;也就是说,以null结尾的字符串最多为
NAME_MAX(即255个)字符,由一个初始斜杠组成,后跟一个或多个字符,其中没有一个是斜杠
所以正确的名字应该是
const char *sharedObj = "/Shm";
sizeof(calcCollatz(atoi(argv[1]))
与sizeof(int*)
相同,即
表示指向int
的指针的大小。因为sizeof
是在
编译时,函数实际上从未执行过。您可能希望按数字调整大小
物品的数量。不仅是ptr+=size
是错误的呼叫,您还得到了
信息完全错误
您的calcCollatz
也是错误的,您只为一个单独的
int
,为什么要为单个int
动态分配空间呢?
而且你现在正在做return collatzSeq
,再说一遍,为什么还要麻烦呢
为单个int
动态分配空间?我想这就是你想要的
寻找:
int *calcCollatz(int n, size_t *len) {
if(len == NULL)
return NULL;
int *collatzSeq = NULL, *tmp = NULL;
*len = 0;
while (n != 1) {
// better than n % 2 == 0
if (n & 1 == 0)
n /= 2;
else
n = 3 * n + 1;
tmp = realloc(collatzSeq, (*len + 1) * sizeof *collatzSeq);
if(tmp == NULL)
{
free(collatzSeq);
return NULL;
}
collatzSeq = tmp;
collatzSeq[(*len)++] = n;
}
return collatzSeq;
}
size_t base = 4096;
size_t arrlen;
int *arr = calcCollatz(atoi(argv[1]), &arrlen);
if(arr == NULL)
{
fprintf(stderr, "failed to do calculation\n");
return 1;
}
size_t size = base + arrlen;
shm_fd = shm_open(sharedObj, O_CREAT | O_RDWR, 0666);
if(shm_fd == -1)
{
fprintf(stderr, "Failed to open shared memory: %s\n", strerror(errno));
return 1;
}
ftruncate(shm_fd, size);
ptrShm = mmap(0, size, PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (ptrShm == MAP_FAILED) {
fprintf(stderr, "Map Failed: %s\n", strerror(errno));
return 1;
}
printf("Writing the sequence to a shared memory object!\n");
sprintf(ptrShm, "%s", argv[1]);
// note that void* arithmetic is a GNU extension
// otherwise you have to cast to (char*) before doing the
// the arithmetic
memcpy(ptrShm + base, arr, arrlen * sizeof *arr);
free(arr);
close(shm_fd);
return 0;
但是如果您坚持以后调整mmap内存的大小,那么您可以使用
,但请注意,这仅在GNU/Linux中可用,并且
在包含sys/mman.h
之前,必须添加#定义"GNU"源代码
:
size_t size = 4096;
// create shared memory + mmap
...
// exapanding mmap memory
size_t arrlen;
int *arr = calcCollatz(atoi(argv[1]), &arrlen);
if(arr == NULL)
{
fprintf(stderr, "failed to do calculation\n");
close(shm_fd);
return 1;
}
size_t newsize = size + arrlen * sizeof *arr;
void *newptrShm = mremap(ptrShm, size, newsize, MREMAP_MAYMOVE);
if(newptrShm == MAP_FAILED)
{
fprintf(stderr, "Failed to expand memory: %s\n", strerror(errno));
free(arr);
close(shm_fd);
return 1;
}
ptrShm = newptrShm;
// resize shared file size
ftruncate(shm_fd, newsize);
memcpy(ptrShm + base, arr, arrlen * sizeof *arr);
free(arr);
...
另见:和
ptr += 代码>某些东西
不是“重新分配空间”或“重新分配内存”;它只是移动一个指针。 (2) 既然您是用C(而不是C++)编程,我建议您减少使用“对象”这个词。 (3) main
中的注释正常。 您的calcCollatz
中缺少注释。 请加一些。 请不要在评论中回复;让你的问题更清楚、更完整。?