C 使用文件描述符使用mmap共享结构数组
我正在尝试使用链表创建一个结构数组,以便在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>
#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);