Использование mmap для реверса текстового файла на месте - ошибка шины
Я думал, что понял это, но я получаю ошибку автобуса. Все, что нужно сделать, это взять какой-нибудь текстовый файл, использовать mmap, а затем перевернуть содержимое без временного файла. То, что я сделал, было сопоставить его, а затем стереть файл и записать его из памяти, начиная с конца указателя mmap. Это сработало, когда я сделал это с Cout, но по какой-то причине, делая это в файл, я получаю сообщение об ошибке.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/io.h>
#include <sys/mman.h>
main(int argc, char *argv[])
{
unsigned char *f, *g;
int size;
struct stat s;
const char * file_name = argv[1];
int fd = open(argv[1], O_RDONLY);
int status = fstat(fd, &s);
size = s.st_size;
int i;
f = (char *) mmap (0, size, PROT_READ, MAP_PRIVATE, fd, 0);
//g = (char *) mmap (0, size, PROT_READ, MAP_PRIVATE, fd, 0);
for(i = 0; i < size; i++) {
char c;
c = f[i];
putchar(c);
}
//ABOVE THIS WORKS
// int z = 0;
//while(f[z] != NULL) {
//z++;
// printf("%d", z);
// }
int x;
int y = 0;
close(fd);
FILE *f1;
f1 = fopen(argv[1], "w+");
for(x = size - 1; x >= 0; x--)
{
char c;
c = f[x];
fputc(c, f1);
}
}
1 ответ
Потому что вы открыли файл с w
Вы обрезали файл до 0 длины. Страница руководства mmap говорит, что:
Эффект изменения размера основного файла сопоставления на страницах, которые соответствуют добавленным или удаленным областям файла, не определен.
В любом случае, мне кажется, что вы должны позвонить mmap
с PROT_WRITE
также, чтобы вы могли просто обратить массив f
в памяти. Тогда вам не нужно снова открывать файл. Убедитесь, что вы используете MMAP_SHARED, а также вызываете munmap() после того, как вы закончили изменение общей памяти. Вам нужен MMAP_SHARED, потому что с MMAP_PRIVATE:
Обновления сопоставления не видны другим процессам, сопоставляющим тот же файл, и не переносятся в базовый файл.
Вы должны вызвать munmap(), потому что:
Файл может не обновляться до тех пор, пока не будет вызван msync (2) или munmap().
Если вы выйдете из программы без вызова munmap(), память для вас автоматически не отобразится. Но это хорошая привычка - закрывать / освобождать / снимать карты самостоятельно, а не просто выходить.
(Изменить: Спасибо Адам Розенфилд и EOF за исправления к моему первоначальному ответу.)