我是使用共享内存的新手,对于第一个文件,实现可以正常工作,但是对于第二个文件,它无法从共享内存中读取一些结构。我认为问题出在我的mmap中,但不太确定到底是什么
第一个文件,效果很好:
struct Sh_Mem* open_res(int nb_tables)
{
size_t mem_size = MEM_SIZE(nb_tables);
int shm_fd=shm_open(MEM_NAME,O_RDWR|O_CREAT | O_TRUNC, 0600);
if(shm_fd<0)
raler("shm_open");
ftruncate(shm_fd,mem_size);
struct Sh_Mem * res=mmap(NULL,mem_size,PROT_READ| PROT_WRITE,MAP_SHARED,shm_fd,0);
if(res == NULL)
raler("mmap");
res->nb_tables=nb_tables;
res->size = mem_size;
return res;
}
int main(int argc, char const *argv[])
{
if (argc < 3)
raler("Usage : ./restaurant <duree_repas> <capacite_des_tables>");
int dinner_time = atoi(argv[1]);
int nb_tables = argc -2;
int fermeture=0;
struct table* tables=malloc(nb_tables*sizeof(struct table));
if (dinner_time < 100 )
raler("Duree de repas tres courte");
struct Sh_Mem* res=open_res(nb_tables);
res->table = malloc(nb_tables*sizeof(struct table));
for(int i = 2; i < (argc); i++)
{
if(atoi(argv[i])>6 || atoi(argv[i])<1 )
{
printf("\nERROR : %s\n ",argv[i] );
raler("Max Capacity of Tables is 6 ");
}
tables[i-2].size = atoi(argv[i]);
}
res->table=tables;
shm_unlink(MEM_NAME);
return 0;
}
第二个文件给我一个分段错误:
struct Sh_Mem* first_guest(char * nom)
{
int shm_fd=shm_open(MEM_NAME,O_RDWR, 0600);
if(shm_fd<0)
raler("shm_open");
struct stat stat;
if(fstat(shm_fd, &stat) < 0) {
perror("fstat");
exit(1);
}
struct Sh_Mem * guests=mmap(NULL,stat.st_size,PROT_READ| PROT_WRITE,MAP_SHARED,shm_fd,0);
if(guests == NULL)
raler("mmap");
return guests;
}
int main(int argc, char const *argv[])
{
if (argc != 3)
raler("Usage : ./convive <nom_du_convive> <nombres_de_personnes_dans_le_groupe/nom_du_premier_convive>");
if(strlen(argv[1])>10)
raler("Name has to be less or equal to 10 char ");
if(isdigit(argv[1][0]))
raler("First argument has to start with a character");
if (isdigit(argv[2][0]))
{
struct Sh_Mem* res=first_guest((char*)argv[1]);
for (int i = 0; i < res->nb_tables; i++)
{
if(res->table[i].used==1)
{
continue;
}
if(res->table[i].size == atoi(argv[2]))
{
found =1;
res->table[i].name=(char *)argv[1];
res->table[i].used =1;
}
printf("%s\n",res->table[i].name );
}
每当我通过res-> tables时,都会发生该错误。我测试了它是否等于null,但它也不是这里的struct:
void raler(char *msg)
{
perror(msg);
exit(1);
}
struct table
{
int id;
int size;
char* name;
int nb_left;
int used;
};
struct Sh_Mem{
int nb_tables;
size_t size;
struct table* table;
};
#define MEM_NAME "/guest"
#define MEM_SIZE(nb_table) sizeof (struct Sh_Mem) + (nb_table)*sizeof (struct convive)+ (nb_table)*sizeof (struct table)
res->table[i].name=(char *)argv[1];
}
printf("%s\n",res->table[i].name );
这是行不通的。你正在将指针放入当前进程的地址空间中,并将其放入共享内存中。这对任何其他过程都没有任何意义。
你可以通过制作name
固定长度的数组或分配一些共享内存并name
指向它来解决此问题。请小心-每个进程都必须计算指向共享内存的正确本地指针,因为不同的进程可能会将同一共享内存段映射到不同的地址。
但是该程序甚至都没有达到这一点,当它遇到
if(res->table[i].used==1)
同样的问题时,它会返回segfault,这是否意味着我必须在结构中分配所有内容同样的问题。如果将指针放在共享内存中,则它们必须是指向共享内存的指针,并且每个进程都必须为它们对该共享内存的特定映射找出正确的指针。可能,您不应该以这种方式使用共享内存。