使用mmap来反转文本文件 - 获取总线错误

时间:2014-11-12 02:55:01

标签: c 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 个答案:

答案 0 :(得分:1)

因为您使用w更改了文件,所以将文件截断为0长度。 mmap手册页说:

  

未指定在与文件的添加或删除区域对应的页面上更改映射的基础文件大小的效果。

无论如何,在我看来,您也应该使用mmap调用PROT_WRITE,这样您就可以在内存中反转数组f。然后,您不必再次打开该文件。确保使用MMAP_SHARED,并在完成修改共享内存后调用munmap()。您需要MMAP_SHARED,因为使用MMAP_PRIVATE:

  

映射更新对映射同一文件的其他进程不可见,并且不会传递到基础文件。

你应该调用munmap(),因为:

  

在调用msync(2)或munmap()之前,文件实际上可能不会更新。

如果在不调用munmap()的情况下退出程序,内存将自动为您取消映射。但是,自己关闭/释放/取消映射事物而不是仅仅退出是一个好习惯。

(编辑:感谢Adam Rosenfield和EOF对我原来答案的更正。)