我正在尝试创建一个包含三个整数和一个数组的共享内存段。创建段并附加指针,但是当我尝试访问变量的值(无论是更改,打印等)时,我都会遇到分段错误。
这是我尝试过的代码:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#define SIZE 10
int* shm_front;
int* shm_end;
int* shm_count;
int* shm_array;
int shm_size = 3*sizeof(int) + sizeof(int[SIZE]);
int main(int argc, char* argsv[])
{
int shmid;
//create shared memory segment
if((shmid = shmget(IPC_PRIVATE, shm_size, 0644)) == -1)
{
printf("error in shmget");
exit(1);
}
//obtain the pointer to the segment
if((shm_front = (int*)shmat(shmid, (void *)0, 0)) == (void *)-1)
{
printf("error in shmat");
exit(1);
}
//move down the segment to set the other pointers
shm_end = shm_front + 1;
shm_count = shm_front + 2;
shm_array = shm_front + 3;
//tests on shm
*shm_end = 10; //gives segmentation fault
printf("\n%d", *shm_end); //gives segmentation fault
//clean-up
//get rid of shared memory
shmdt(shm_front);
shmctl(shmid, IPC_RMID, NULL);
printf("\n\n");
return 0;
}
我尝试通过解除引用结构的指针来访问共享内存,但每次都会出现分段错误。
谢谢大家,现在没有分段错误。
答案 0 :(得分:2)
在您的代码中,您没有包含sys/shm.h
,这会导致您的编译器吐出这些:
warning: implicit declaration of function ‘shmget’
warning: implicit declaration of function ‘shmat’
warning: implicit declaration of function ‘shmdt’
warning: implicit declaration of function ‘shmctl’
将shmat
的返回值转换为int *
也会隐藏此警告:
warning: assignment makes pointer from integer without a cast
这里可能会发生的事情是,由于未定义shmat
,编译器将隐式地返回int
而不是void *
。如果它返回的地址不符合有符号整数,则会出现整数溢出,这是未定义的行为,并且很可能导致分段错误以访问未分配的内存位置。
你不应该强制转换返回void *
的函数的返回值来捕获这些错误(并且总是在启用警告的情况下编译)。
答案 1 :(得分:1)
我不知道这是你唯一的问题,但这一行
int shm_size = 3*sizeof(int) + sizeof(shm_array[SIZE]);
最有可能不是你想要的。 sizeof(shm_array[SIZE])
只是int
的大小,而不是数组的大小。如果您需要,请使用sizeof(int[SIZE])
。
通常我发现共享片段的现代界面shm_open
更容易使用。它的工作方式类似于文件打开和映射,并且对段大小的约束较少。
答案 2 :(得分:0)
这真的是一个改进的问题,但格式化程序将其搞砸并使其无法读取,所以我将其转移到答案......
也许我只是在看这个问题,但你的指针不会如下:
shm_end = shm_front;
shm_count=shm_front+1
shm_array=shm_front+2;
第一个整数将存储在块的头部,正好在shm_front,然后就行了......除非共享内存块包含偏移0处的一些相关信息,否则我不知道为什么你将这些偏移一个......只是观察。