書き込み用のリンクリストを使用して構造体の配列を作成し、mmapで読み込もうとしています。配列データを読み込もうとすると、セグメンテーションフォルトが発生します。ファイル記述子を使用して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);
}
読むコード:
#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);
}
Readコードの 'ini()'の 'strcpy(dog-> nombre、"); 'で' NULL'を間接的に指定すると、セグメンテーションフォルトが発生する可能性が大きくなります。 'dog'を使う前に、いくつかのメモリを割り当ててポインタを割り当てます。 – MikeCAT
注:[あなたは 'malloc()'の結果をCでキャストすべきではないと言います(http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc)。 – MikeCAT
既存の変数のアドレスを 'mmap()'の引数として与えることはできません。そのアドレスはすでに非共有メモリに使用されています。共有することはできません。 – Barmar