I'm new to using shared memory and for the first file the implementation is working fine but for the second file it is unable to read some of the structures from the shared memory . I think the problem is in my mmap but not quite sure what exactly
first file which works nicely:
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;
}
Second file which give me a segmentation fault :
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 );
}
the error happens whenever i pass by a res->tables. i tested if it was equal to null but it isn't also here is the 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 );
This doesn't work. You are putting a pointer into the current process' address space into shared memory. This means nothing to any other process.
You can fix this by making name
a fixed-length array or by allocating some shared memory and having name
point to that. Just be careful -- each process will have to compute the correct local pointer to the shared memory since different processes may map the same shared memory segment at different addresses.
but the program doesn't even get to this point it returns segfault when it gets to
if(res->table[i].used==1)
is it the same problem and does that mean i have to allocate everything in the structureSame problem. If you put pointers in shared memory, they have to be pointers to shared memory and every process has to figure out the correct pointer for their particular mapping of that shared memory. Likely, you just shouldn't be using shared memory this way.