2012-04-15 8 views
4

mmapをC言語で使って、正しく動作するかどうかを確認しようとしています。現在、mmapを使用してバイナリファイルをバイト単位で読み込もうとしています。私のコードは次のようなものです:SegfaultはCでmmapを使ってバイナリファイルを読み込みます

#include <unistd.h> 
#include <sys/types.h> 
#include <sys/mman.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <fcntl.h>  

int main(int argc, char *argv[]) { 
    int fd; 
    char *data; 

    for (int i = 1; i<argc; i++) 
    { 

     if(strcmp(argv[i],"-i")==0) 
      fd = open(argv[i+1],O_RDONLY); 
    } 

    data = mmap(NULL, 4000, PROT_READ, MAP_SHARED, fd, 8000); 
    int i = 0; 
    notation = data [i]; 
    // ...... 

} 

私はnotation = data [0]を試して、segfaultを取得すると問題が発生します。私は、バイナリファイルの最初のバイトも文字であることを確信しています。私のforループはコンパイル時に-iフラグがあるかどうかをチェックし、次の引数がある場合はファイル名にします。

+0

ファイルのサイズは8000バイト以上ですか?また、マニュアルページには、 "オフセットはsysconf(_SC_PAGE_SIZE)によって返されるページサイズの倍数でなければなりません"と記載されています。もしユーザが-iパラメータを指定せず、forループがargc-1までループする必要がある場合には、fdを-1に初期化する必要があります。それ以外の場合は、ユーザが指定した場合を超えてargvにアクセスします。私は最後のパラメータとして。 – EricS

答えて

4

オフセットがページサイズの倍数ではないため、mmapが失敗するようです。これをperrorでテストし、問題が無効な引数であることを確認することができます。あなたが書く場合:

少なくとも私のOS X上で次のエラーがプリントされ
data = mmap(NULL, 4000, PROT_READ, MAP_SHARED, fd, 8000); 
perror("Error"); 

エラー:無効な引数を

は4096人のまたは8192作品への8000からのオフセットを変更します。 6144はそうではないので、このプラットフォームで4096の倍数でなければなりません。ところで、

printf("%d\n",getpagesize()); 

印刷物4096あなたのmmapのために、このの最も近い倍数にまでオフセットやエリアにアクセスするとき、私に余りを追加丸める必要があります。もちろん、その機能から特定のプラットフォームのページサイズを取得します。おそらくあなたがすでに宣言しているunistd.hで定義されています。

オフセットを正しく処理し、起こりうるエラーに対処する方法は次のとおりです。これは、8000の位置にバイトを出力します。

int offset = 8000; 
int pageoffset = offset % getpagesize(); 

data = mmap(NULL, 4000 + pageoffset, PROT_READ, MAP_SHARED, fd, offset - pageoffset); 
if (data == MAP_FAILED) { 
    perror ("mmap"); 
    exit (EXIT_FAILURE); 
} 
i = 0; 
printf("%c\n",data [i + pageoffset]); 
+0

+1よく見つかった:-) – cnicutar

+0

これをすべて実行した後も、データは空になってしまいます。しかし、私のbinファイルのサイズは16MBです。何かご意見は ? – AndroidDev93

+0

その後、データで何をやっていますか?私はpageoffsetも長さ4000に追加しなければならないことに気付きました。現在のコードでは、8000から11999バイトにアクセスできるはずです。 – jjrv

関連する問題