C 使用文件描述符使用mmap共享结构数组

C 使用文件描述符使用mmap共享结构数组,c,struct,linked-list,mmap,C,Struct,Linked List,Mmap,我正在尝试使用链表创建一个结构数组,以便在mmap中写入和读取它们。我在尝试读取阵列数据时遇到分段错误 我确信这个问题与我使用指针的方式有关,因为我使用的是不同的结构 编写代码: #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h>

我正在尝试使用链表创建一个结构数组,以便在mmap中写入和读取它们。我在尝试读取阵列数据时遇到分段错误

我确信这个问题与我使用指针的方式有关,因为我使用的是不同的结构

编写代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

struct dogType
  {
    char nombre[32];
    int edad;
    char raza[16];
    int estatura;
    float peso;
    char sexo;
  };

struct dogType *dog;

struct test_struct
{
    struct dogType dog;
    struct test_struct *next;
};

struct node
{
    struct test_struct *head;
    struct test_struct *curr;
};

struct node nodes[10];
struct node *map;

int i;
long counter = 0;

struct test_struct* add_to_list(struct dogType *pet, bool add_to_end, int hashnumber);

void ini(void)
{

    strcpy(dog->nombre, "");
           dog->edad = 0;
           strcpy(dog->raza, "");
           dog->estatura = 0;
           dog->peso = 0;
           dog->sexo = ' ';

    for(i = 0; i < 10; i++)
    {
        add_to_list(dog, false, i);
    }
}


struct test_struct* create_list(struct dogType *pet, int hashnumber)
{
    struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));

    if(NULL == ptr)
    {
    printf("\n Node creation failed \n");
    return NULL;
    }
    ptr->dog = *pet;
    ptr->next = NULL;

    map[hashnumber].head = map[hashnumber].curr = ptr;
    return ptr;
}



struct test_struct* add_to_list(struct dogType *pet, bool add_to_end, int hashnumber)
{

    if(NULL == ( map[hashnumber].head))
    {
    return (create_list(pet, hashnumber));
    }

    struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
    if(NULL == ptr)
    {
    printf("\n Node creation failed \n");
    return NULL;
    }

    ptr->dog = *pet;
    ptr->next = NULL;

    if(add_to_end)
    {
     map[hashnumber].curr->next = ptr;
     map[hashnumber].curr = ptr;
    }
    else
    {
    ptr->next = map[hashnumber].head;
    map[hashnumber].head = ptr;
    }

    counter++;
    return ptr;
}

struct test_struct* search_in_list(char * name, struct test_struct **prev, int hashnumber)
{
    struct test_struct *ptr =  map[hashnumber].head;
    struct test_struct *tmp = NULL;
    bool found = false;

    printf("\n Searching the list for value [] \n");

    while(ptr != NULL)
    {
       char *asd=ptr->dog.nombre;
       if(strcmp(asd, name) == 0)
    {
        found = true;
        break;
    }
    else
    {
        tmp = ptr;
        ptr = ptr->next;
    }
    }

    if(true == found)
    {
    if(prev)
        *prev = tmp;
    return ptr;
    }
    else
    {
    return NULL;
    }
}


int delete_from_list(char * name, int hashnumber)
{
    struct test_struct *prev = NULL;
    struct test_struct *del = NULL;

    del = search_in_list(name, &prev, hashnumber);
    if(del == NULL)
    {
    return -1;
    }
    else
    {
    if(prev != NULL)
        prev->next = del->next;

    if(del ==  map[hashnumber].curr)
    {
         map[hashnumber].curr = prev;
    }
    else if(del ==  map[hashnumber].head)
    {
         map[hashnumber].head = del->next;
    }
    }

    free(del);
    del = NULL;
    counter--;

    return 0;
}

void print_list(int hashnumber)
{
    struct test_struct *ptr =  map[hashnumber].head;

    printf("\n -------Printing list Start------- \n");
    while(ptr != NULL)
    {
    printf
    ("\n%s%s", "Nombre: ", ptr->dog.nombre);

    ptr = ptr->next;
    }
    printf("\n -------Printing list End------- \n");

    return;
}

void main(void)
{

    map = nodes;
    dog = malloc(sizeof (struct dogType));
    ini();

       strcpy(dog->nombre, "perrito");
       dog->edad = 15;
       strcpy(dog->raza, "chanda");
       dog->estatura = 15;
       dog->peso = 15;
       dog->sexo = 'm';

    char *filepath = "temp.dat";

    int fd = open(filepath, O_RDWR | O_CREAT , (mode_t)0600);

    if (fd == -1)
    {
    perror("Error opening file for writing");
    exit(EXIT_FAILURE);
    }

    size_t textsize = sizeof(nodes);

    if (lseek(fd, textsize-1, SEEK_SET) == -1)
    {
    close(fd);
    perror("Error calling lseek() to 'stretch' the file");
    exit(EXIT_FAILURE);
    }

    if (write(fd, "", 1) == -1)
    {
    close(fd);
    perror("Error writing last byte of the file");
    exit(EXIT_FAILURE);
    }

    map = mmap(nodes, sizeof(nodes), PROT_READ | PROT_WRITE,  MAP_SHARED, fd, 0);
    if (map == MAP_FAILED)
    {
    close(fd);
    perror("Error mmapping the file");
    exit(EXIT_FAILURE);
    }


    add_to_list(dog, false, 1);
    print_list(1);

    if (msync(map, sizeof(nodes), MS_SYNC) == -1)
    {
    perror("Could not sync the file to disk");
    }

    if (munmap(map, sizeof(nodes)) == -1)
    {
    close(fd);
    perror("Error un-mmapping the file");
    exit(EXIT_FAILURE);
    }

    close(fd);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
结构狗型
{
字符名称[32];
国际教育署;
char raza[16];
国际遗产;
浮动比索;
char sexo;
};
结构狗型*狗型;
结构测试
{
结构狗型狗;
结构测试_struct*next;
};
结构节点
{
结构测试\结构*头;
结构测试\结构*电流;
};
结构节点[10];
结构节点*映射;
int i;
长计数器=0;
结构测试?结构*将?添加到?列表(结构狗型*宠物,布尔添加到?结尾,整数哈希数);
无效ini(无效)
{
strcpy(dog->nombre,“”);
狗->edad=0;
strcpy(狗->拉扎,”;
狗->estatura=0;
狗->比索=0;
狗->性感='';
对于(i=0;i<10;i++)
{
将_添加到_列表(dog、false、i);
}
}
结构测试\u结构*创建\u列表(结构dogType*pet,int hashnumber)
{
结构测试(struct test_struct*ptr=(struct test_struct*)malloc(sizeof(struct test_struct));
if(NULL==ptr)
{
printf(“\n节点创建失败\n”);
返回NULL;
}
ptr->狗=*宠物;
ptr->next=NULL;
map[hashnumber].head=map[hashnumber].curr=ptr;
返回ptr;
}
结构测试\u结构*将\u添加到\u列表(结构dogType*pet、bool添加到\u end、int hashnumber)
{
if(NULL==(映射[hashnumber].head))
{
返回(创建_列表(宠物、hashnumber));
}
结构测试(struct test_struct*ptr=(struct test_struct*)malloc(sizeof(struct test_struct));
if(NULL==ptr)
{
printf(“\n节点创建失败\n”);
返回NULL;
}
ptr->狗=*宠物;
ptr->next=NULL;
如果(将_添加到_末尾)
{
map[hashnumber].curr->next=ptr;
map[hashnumber].curr=ptr;
}
其他的
{
ptr->next=map[hashnumber].head;
map[hashnumber].head=ptr;
}
计数器++;
返回ptr;
}
结构测试\u结构*搜索\u列表中的\u(字符*名称,结构测试\u结构**prev,int hashnumber)
{
struct test_struct*ptr=map[hashnumber].head;
struct test_struct*tmp=NULL;
bool-found=false;
printf(“\n在列表中搜索值[]\n”);
while(ptr!=NULL)
{
char*asd=ptr->dog.nombre;
if(strcmp(asd,名称)==0)
{
发现=真;
打破
}
其他的
{
tmp=ptr;
ptr=ptr->next;
}
}
if(true==found)
{
如果(上一个)
*prev=tmp;
返回ptr;
}
其他的
{
返回NULL;
}
}
int从_列表中删除_(字符*名称,int哈希编号)
{
结构测试_struct*prev=NULL;
结构测试_struct*del=NULL;
del=在列表中搜索(名称、上一个和哈希编号);
如果(del==NULL)
{
返回-1;
}
其他的
{
如果(上一个!=NULL)
上一步->下一步=删除->下一步;
if(del==map[hashnumber].curr)
{
map[hashnumber].curr=prev;
}
else if(del==map[hashnumber].head)
{
映射[hashnumber].head=del->next;
}
}
免费(del);
del=NULL;
计数器--;
返回0;
}
无效打印列表(整数哈希编号)
{
struct test_struct*ptr=map[hashnumber].head;
printf(“\n-------打印列表开始--------\n”);
while(ptr!=NULL)
{
printf
(“\n%s%s”,“Nombre:”,ptr->dog.Nombre);
ptr=ptr->next;
}
printf(“\n-------打印列表结束--------\n”);
返回;
}
真空总管(真空)
{
map=节点;
dog=malloc(sizeof(struct dogType));
ini();
strcpy(dog->nombre,“perrito”);
狗->edad=15;
strcpy(狗->拉扎,“钱达”);
狗->estatura=15;
狗->比索=15;
狗->性感='m';
char*filepath=“temp.dat”;
int fd=打开(文件路径,O|U RDWR | O|U CREAT,(模式)0600);
如果(fd==-1)
{
perror(“打开文件进行写入时出错”);
退出(退出失败);
}
size\t textsize=sizeof(节点);
if(lseek(fd,textsize-1,SEEK_SET)=-1)
{
关闭(fd);
perror(“调用lseek()以“拉伸”文件时出错”);
退出(退出失败);
}
如果(写入(fd,“,1)=-1)
{
关闭(fd);
perror(“写入文件最后一个字节时出错”);
退出(退出失败);
}
map=mmap(节点,大小(节点),PROT_READ | PROT_WRITE,map_SHARED,fd,0);
if(map==map\u失败)
{
关闭(fd);
perror(“映射文件时出错”);
退出(退出失败);
}
将_添加到_列表(dog,false,1);
打印列表(1);
if(msync(map,sizeof(nodes),MS_SYNC)=-1)
{
perror(“无法将文件同步到磁盘”);
}
if(munmap(map,sizeof(nodes))=-1)
{
关闭(fd);
perror(“取消映射文件时出错”);
退出(退出失败);
}
关闭(fd);
}
阅读代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdint.h>

struct dogType
{
    char nombre[32];
    int edad;
    char raza[16];
    int estatura;
    float peso;
    char sexo;
};

struct dogType *dog;

struct test_struct
{
    struct dogType dog;
    struct test_struct *next;
};

struct node
{
    struct test_struct *head;
    struct test_struct *curr;
};

struct node nodes[10];
struct node *map;

int i;
long counter = 0;

struct test_struct* add_to_list(struct dogType *pet, bool add_to_end, int hashnumber);


void ini(void)
{
    strcpy(dog->nombre, "");
    dog->edad = 0;
    strcpy(dog->raza, "");
    dog->estatura = 0;
    dog->peso = 0;
    dog->sexo = ' ';

    for(i = 0; i < 10; i++)
    {

        add_to_list(dog, false, i);
    }
}


struct test_struct* create_list(struct dogType *pet, int hashnumber)
{
    struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));

    if(NULL == ptr)
    {
    printf("\n Node creation failed \n");
    return NULL;
    }
    ptr->dog = *pet;
    ptr->next = NULL;

    map[hashnumber].head = map[hashnumber].curr = ptr;
    return ptr;
}



struct test_struct* add_to_list(struct dogType *pet, bool add_to_end, int hashnumber)
{

    if(NULL == ( map[hashnumber].head))
    {
    return (create_list(pet, hashnumber));
    }

    struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
    if(NULL == ptr)
    {
    printf("\n Node creation failed \n");
    return NULL;
    }

    ptr->dog = *pet;
    ptr->next = NULL;

    if(add_to_end)
    {
     map[hashnumber].curr->next = ptr;
     map[hashnumber].curr = ptr;
    }
    else
    {
    ptr->next = map[hashnumber].head;
    map[hashnumber].head = ptr;
    }

    counter++;
    return ptr;
}

struct test_struct* search_in_list(char * name, struct test_struct **prev, int hashnumber)
{
    struct test_struct *ptr =  map[hashnumber].head;
    struct test_struct *tmp = NULL;
    bool found = false;

    printf("\n Searching the list for value [] \n");

    while(ptr != NULL)
    {
       char *asd=ptr->dog.nombre;
       if(strcmp(asd, name) == 0)
    {
        found = true;
        break;
    }
    else
    {
        tmp = ptr;
        ptr = ptr->next;
    }
    }

    if(true == found)
    {
    if(prev)
        *prev = tmp;
    return ptr;
    }
    else
    {
    return NULL;
    }
}


int delete_from_list(char * name, int hashnumber)
{
    struct test_struct *prev = NULL;
    struct test_struct *del = NULL;

    del = search_in_list(name, &prev, hashnumber);
    if(del == NULL)
    {
    return -1;
    }
    else
    {
    if(prev != NULL)
        prev->next = del->next;

    if(del ==  map[hashnumber].curr)
    {
         map[hashnumber].curr = prev;
    }
    else if(del ==  map[hashnumber].head)
    {
         map[hashnumber].head = del->next;
    }
    }

    free(del);
    del = NULL;
    counter--;

    return 0;
}

void print_list(int hashnumber)
{
    struct test_struct *ptr =  map[hashnumber].head;

    printf("\n -------Printing list Start------- \n");
    while(ptr != NULL)
    {
    printf
    ("\n%s%s", "Nombre: ", ptr->dog.nombre);

    ptr = ptr->next;
    }
    printf("\n -------Printing list End------- \n");

    return;
}

void main(void)
{

    ini();

    dog = malloc(sizeof (struct dogType));
    strcpy(dog->nombre, "perrito");
    dog->edad = 15;
    strcpy(dog->raza, "chanda");
    dog->estatura = 15;
    dog->peso = 15;
    dog->sexo = 'm';

    const char *filepath = "temp.dat";

    int fd = open(filepath, O_RDONLY, (mode_t)0600);

    if (fd == -1)
    {
    perror("Error opening file for writing");
    exit(EXIT_FAILURE);
    }        

    struct stat fileInfo = {0};

    if (fstat(fd, &fileInfo) == -1)
    {
    perror("Error getting the file size");
    exit(EXIT_FAILURE);
    }

    if (fileInfo.st_size == 0)
    {
    fprintf(stderr, "Error: File is empty, nothing to do\n");
    exit(EXIT_FAILURE);
    }

    printf("File size is %ji\n", (intmax_t)fileInfo.st_size);

    struct node *map = mmap(nodes, fileInfo.st_size, PROT_READ, MAP_SHARED, fd, 0);

    if (map == MAP_FAILED)
    {
    close(fd);
    perror("Error mmapping the file");
    exit(EXIT_FAILURE);
    }

    print_list(3);

    if (munmap(map, fileInfo.st_size) == -1)
    {
    close(fd);
    perror("Error un-mmapping the file");
    exit(EXIT_FAILURE);
    }

    close(fd);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
结构狗型
{
字符名称[32];
国际教育署;
char raza[16];
国际遗产;
浮动比索;
char sexo;
};
结构狗型*狗型;
结构测试
{
结构狗型狗;
结构测试_struct*next;
};
结构节点
{
结构测试\结构*头;
结构测试\结构*电流;
};
结构节点[10];
结构节点*映射;
int i;
长计数器=0;
结构测试?结构*将?添加到?列表(结构狗型*宠物,布尔添加到?结尾,整数哈希数);
无效ini(无效)
{
strcpy(dog->nombre,“”);
狗->edad=0;
strcpy(狗->拉扎,”;
狗->estatura=0;
狗->比索=0;
狗->性感='';
对于(i=0;i<10;i++)
{
将_添加到_列表(dog、false、i);
}
}
结构测试\u结构*创建\u列表(结构dogType*pet,int hashnumber)
{
结构测试(struct test_struct*ptr=(struct test_struct*)malloc(sizeof(struct test_struct));
if(NULL==ptr)
{
printf(“\n节点创建失败\n”
int fd = shm_open("/dog_storage", oflags, mode);

pointer = mmap(NULL, length, prot, mmap_flags, fd, offset);