从共享内存读取数组时出现 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[];
};