从共享内存读取数组时出现 SEGFAULT
getting SEGFAULT when reading an array from shared memory
我刚开始使用共享内存,对于第一个文件,实现工作正常,但对于第二个文件,它无法从共享内存中读取某些结构。我认为问题出在我的 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 但它不是
这也是结构:
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 );
这行不通。您正在将指向当前进程地址 space 的指针放入共享内存中。这对任何其他进程都没有任何意义。
您可以通过使 name
成为固定长度的数组或分配一些共享内存并让 name
指向它来解决这个问题。请注意——每个进程都必须计算正确的 local 指向共享内存的指针,因为不同的进程可能会在不同的地址映射相同的共享内存段。
我所要做的就是将结构从动态更改为静态,它工作正常
struct Sh_Mem{
int nb_tables;
size_t size;
struct table table[];
};
我刚开始使用共享内存,对于第一个文件,实现工作正常,但对于第二个文件,它无法从共享内存中读取某些结构。我认为问题出在我的 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 但它不是 这也是结构:
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 );
这行不通。您正在将指向当前进程地址 space 的指针放入共享内存中。这对任何其他进程都没有任何意义。
您可以通过使 name
成为固定长度的数组或分配一些共享内存并让 name
指向它来解决这个问题。请注意——每个进程都必须计算正确的 local 指向共享内存的指针,因为不同的进程可能会在不同的地址映射相同的共享内存段。
我所要做的就是将结构从动态更改为静态,它工作正常
struct Sh_Mem{
int nb_tables;
size_t size;
struct table table[];
};