Почему я получаю ошибку сегментации? Я использую stat, mmap, nftw и memcmp, между прочим
Вот мой код Я предполагаю, что это как-то связано с неправильным использованием указателей или, может быть, я неправильно отображаю и удаляю карту из памяти.
Может ли кто-нибудь дать мне некоторое представление об этой проблеме?
#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <ftw.h>
#include <sys/stat.h>
#include <string.h>
int size;
int map1, map2;
void *tar, *temp;
int callback(const char *filename,
const struct stat *sb2,
int filetype,
struct FTW *ftw)
{
printf("test");
if(sb2->st_size == sb1->st_size){
temp = mmap(NULL, sb2->st_size, PROT_NONE, 0, map2, 0);
int cmp = memcmp(tar, temp, sb2->st_size);
printf("%d\n", cmp);
if(cmp == 0){
printf("%s\n", filename);
}
if(munmap(temp,sb2->st_size) == -1){
fprintf(stderr, "Error in unmapping in callback function");
exit(EXIT_FAILURE);
}
}
return 0; //continue to walk the tree
}
int main(int argc, char *argv[])
{
//check for correct arguments
if (argc == 1 || argc > 3) {
fprintf(stderr, "Syntax: %s filename dirname\n", argv[0]);
exit(EXIT_FAILURE);
}
//use stat to get size of filename
struct stat sb1;
if(stat(argv[1],&sb1) != 0){
fprintf(stderr, "Error in stat().");
exit(EXIT_FAILURE);
}
size = sb1.st_size;
//fd = mmap filename
tar = mmap(NULL,sb1->st_size, PROT_WRITE, MAP_SHARED, map1, 0);
if(tar == 0){
fprintf(stderr, "Main() mmap failed");
exit(EXIT_FAILURE);
}
//walk through the directory with callback function
nftw(argv[2], callback, 20, 0);
// use munmap to clear fd
if (munmap(tar,sb1->st_size) == -1) {
fprintf(stderr, "Error in unmapping");
exit(EXIT_FAILURE);
}
}
РЕДАКТИРОВАТЬ
Теперь я объявляю свою структуру stat sb1 непосредственно перед использованием функции stat. После этого я снова получил ошибку сегментации. Затем я закомментировал свой вызов nftw() и распечатал переменную размера (которая имеет разумное число, поэтому я считаю, что это работает). Новая ошибка:
Ошибка в отображении.
2 ответа
Вы заявляете:
struct stat *sb1;
Ты используешь:
stat(argv[1],sb1);
Вы терпите крах и горите, потому что sb1
является нулевым указателем (поскольку переменная определена в области видимости файла, она инициализируется 0).
Вы должны объявить (в области видимости файла):
struct stat sb1;
А потом в main()
ты можешь использовать:
if (stat(argv[1], &sb1) != 0)
...oops...
Вам придется рассмотреть все варианты использования sb1
исправить изменение статуса от указателя к объекту, добавив &
где необходимо, и меняется ->
в .
где необходимо.
mmap () на примере
Это слегка отредактированная версия функции, которую я написал, которая использует mmap()
чтобы отобразить файл в память:
/* Map named file into memory and validate that it is a MSG file */
static int msg_mapfile(const char *file)
{
int fd;
void *vp;
struct stat sb;
if (file == 0)
return(MSG_NOMSGFILE);
if ((fd = open(file, O_RDONLY, 0)) < 0)
return(MSG_OPENFAIL);
if (fstat(fd, &sb) != 0)
{
close(fd);
return(MSG_STATFAIL);
}
vp = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
if (vp == MAP_FAILED)
return(MSG_MMAPFAIL);
Константы MSG_xxxx - это отдельные номера ошибок, применимые к программе, из которой они получены. Нужно было только прочитать файл, следовательно, PROT_READ
; Я думаю, что вы можете быть в порядке с этим тоже.
if (argc == 1 || argc > 3) {
fprintf(stderr, "Syntax: %s filename dirname\n", argv[0]);
exit(EXIT_FAILURE);
}
/* ... */
nftw(argv[2], callback, 20, 0);
Я вижу возможность для argv[2] быть NULL. Возможно, вы имели в виду:
if (argc != 3) {
fprintf(stderr, "Syntax: %s filename dirname\n", argv[0]);
exit(EXIT_FAILURE);
}
Какую книгу ты читаешь?