2016-03-24 26 views
0

私のプログラムがファイルから奇妙な値を読み取る理由を教えてください。私はmmapを使ってファイルを読み込もうとしています。私がこの機能を使用する理由は、それがどのように機能するかを理解することです。次に、特定の物理メモリアドレスでバイナリデータを読み込むために、/ dev/memと一緒に使用します。mmap()でバイナリファイルを読む

次のpythonスクリプトを使用して、ファイル 'hello1.raw'を作成しました。

fd = open("hello1.raw", "w+b") 
fd.write(b'01') 

fd.close() 

次に、以下のcプログラムを使用して読み込もうとしました。

しかし、このプログラムは奇妙な値を表示します。

address of hello.raw: 0x10238d000 
data in hello.raw: 12592 

データは、まず01ではないが12592.

+0

'd.write(b'01 ')'それはどういう意味ですか?文字定数? 'write()'は3つの引数、ファイル記述子のint、データのバッファ(またはポインタ)、サイズのintを要求します。 (これはPythonです)。実際の内容を見るには、od -CXまたはhexdumpを使用してください。 BTW:mmap()は、メモリページで動作します。あなたは物理的なEOFを超えて何もするべきではありません。 – joop

+0

@joopあなたの答えをありがとう。つまり、hello1.rawファイルにバイナリ値01が含まれていないということですか? – SD11

+0

私が言ったように:hexdumpまたはod -Xを使って内容を確認します。 lsを使用して、サイズとモードを確認します。 – joop

答えて

1
#include <stdio.h> 
#include <sys/stat.h> 

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

int main(){ 

int fd, rc , ii; 
int *ptr; 
struct stat st; 
size_t size; 

fd = open("hello1.raw", O_RDWR); 

rc = fstat(fd, &st); 
fprintf(stderr, "stat() = %d\n", rc); 
size=st.st_size; 
fprintf(stderr, "size=%zu\n", size); 

ptr = mmap(0, size, PROT_READ|PROT_EXEC ,MAP_SHARED , fd, 0); 
fprintf(stderr, "address of hello1.raw: %p\n", ptr); 

for (ii=0; ii < size/sizeof *ptr; ii++) { 
    printf("data in raw[%d]: %d\n", ii, ptr[ii]); 
     } 

rc = munmap(ptr, size); 
fprintf(stderr, "unmap() = %d\n", rc); 
close(fd); 

return 0; 
} 

  • :システムコールの戻り値をチェックして、stderrに報告します。
  • 2番目:mmap()はページで動作します。 st.st_sizeがページサイズの倍数でない場合は、切り上げられます。
  • hello1.rawファイル(4バイト)に "OMG \ n"を入れてテストし、プログラムを実行します。
  • ) - >> "OM \ n")endプログラムを再実行します。

結果1:

$ ./a.out 
stat() = 0 
size=4 
address of hello1.raw: 0xa64000 
data in raw[0]: 172445007 
unmap() = 0 

結果2:

$ ./a.out 
stat() = 0 
size=3 
address of hello1.raw: 0xe37000 
unmap() = 0 

説明:最初の実行でファイルが持つサイズ= 4、MMAPが成功し、且つintが出力されます。 (sizeof intは4です)。 の場合は、の場合は、上位バイト(ここではBigエンディアンと仮定します)を越える参照は許可されますが、mmapは成功しますが、intは出力されません(ループの私のバージョンはeofを超えたmmappedメモリを参照しません)。 int値はゼロとして表示されます。なぜなら、システムはゼロをページに埋め込んでいるからです。

ヌルパディングの効果を確認する場合は、forループをfor (ii=0; ii <= size/sizeof *ptr; ii++) {に変更し、上記の実験を繰り返します。

関連する問題