mmap()関数の引数の違いによる挙動の違いとは?

このQ&Aのポイント
  • mmap()関数の第一引数にNULLを指定した場合と特定のアドレスを指定した場合の挙動の違いが分からない。
  • NULLを指定した場合は、kernelが適切な仮想アドレスを割り当てる。
  • 特定のアドレスを指定した場合は、mmap()の戻り値はその指定アドレスになる。
回答を見る
  • ベストアンサー

mmap()

mmap()の第一引数(仮にstartとします)にNULLを指定した場合と 特定のアドレスを指定した場合の挙動の違いが判らないのですが 御存知の方おられましたら、御教授頂けませんでしょうか 今、理解できているのは ・NULL指定した場合は、kernelにおまかせで仮想アドレスを割り当ててもらう。 ・startに特定アドレスを指定した場合は、mmap()の戻り値はstartに指定したアドレスになる。(当然か。。。) ※また、startにNULLを指定した場合はキャッシャブルで特定アドレスを指定した場合は、非キャッシャブルという記述をどこかのHPで見かけたのですが、この意味がわかりません。どなたか御教授頂けると助かります。 宜しくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • chirubou
  • ベストアンサー率37% (189/502)
回答No.1

・NULL指定した場合は、kernelにおまかせで仮想アドレスを割り当ててもらう。 ・startに特定アドレスを指定した場合は、mmap()の戻り値はstartに指定したアドレスになる。(当然か。。。) ----- その通りです。私は NULL を指定したことしかありません。なぜなら、mmap() を複数回行うと、それぞれのアドレス範囲が重ならないように注意しなければなりませんから。NULL だと kernel が自動的にやってくれますので、この心配がありません。 逆に strart アドレスを指定する方が、一般に少ないと思います。mmap() は shared library とか、場合によっては malloc() とかからでも呼び出される事があり、特に shared library のアドレスは kernel が決め打ちだったりします。ということで、mmap() の start アドレスは、実際には任意の値とすることができないので、プロセスのアドレスマップに精通するなど、かなり注意を要します。 間違って既に mmap() してある領域に新たに mmap() すると、どうなるか、これは kernel 依存だったような気がします。物によってはエラーにならずに黙って mmap() して、mmap() したとたん今までとは違ったメモリの内容が見えたりすると、かなり原因究明に困難をきたす事も考えられます。 「キャッシャブル」云々はカーネル内での mmap の話ではありませんか?PCI デバイスなどの PCI アドレスにマップされたデバイスのメモリをアクセスする場合、デバイスが I/O 等の結果により自分(デバイス)のメモリ(これは 例えば PCI カードに乗っているメモリで、普通にいうメモリではない)を書き換えてしまうと、CPU のキャッシュにはその変更が反映されないため、非常に困ったことが起きます。このためデバイスが自分のメモリを書き換える時は、「このデバイスのメモリはキャッシュしないでマップする」というようにします。もちろんこうするとこのページへのアクセスは遅くなりますが、仕方がないですよね。 Linux だと PCI デバイスのマップは "/sbin/lspci -v" とかで見ることができます。

関連するQ&A

  • mmap()した領域の領域確保

    mmapで特定のデバイスのIOメモリを仮想空間に割り付けて, その領域に対してユーザーからデータを書き込むことを考えています. ユーザープログラム側でその領域上に,ある構造体の双方向リスト を作りたいのですが,ユーザー空間の特定のアドレス範囲から空き メモリ領域を動的に確保する方法はないでしょうか void *vm_malloc(start_address, end_adress, nbyte); とすると"仮想アドレスstart_address~end_adressの範囲から空き領域を探し出し, nbyteバイトの領域を確保する"みたいなイメージです 一連の流れとしては,struct hogeをIOメモリに書き込む場合,  ・mmap()でIOメモリを仮想空間にマップ  ・struct hoge* addr = vm_malloc();でマップされた領域からsizeof(struct hoge)だけ領域を確保  ・*addr = .....;  ・vm_malloc, データの書き込みの繰り返し  ・fsync() のようなことをしたいと考えています.

  • C#による.NETストアドプロシージャ

    VisualStudio+ODT.netで、C#にて「.NETストアドプロシージャ」を製作しようとしています。 例えばNUMBER型の値を引数で渡してNUMBER型値を返す様なFUNCTIONを作りたいとして、 Oracle側で使う際にNUMBER型の値にはNULL値も有り得るわけですが、 C#側でメソッドの引数や戻り値に、NULL許容型(int?やdecimal?とか)を指定してビルドし、 それをVisualStudioからOracleデータベースへデプロイしようとすると、 ウィザード上のパラメータマッピングのところで、NULL許容型に指定した引数や戻り値に対して Oracle側の適切なデータ型を指定出来なくなってしまいます。 かと言って、C#側メソッドでNULL許容型ではない型を指定してしまいますと、引数へNULL値を 与えると例外が発生してしまいます。 この様な問題に直面されて、何らか解決された方はいらっしゃいますでしょうか?

  • ID を引数にとる場合の記述方法

    MFC のダイアログベースでプログラミングをしています。 関数について、引数の記述方法が分からずに困っています。 以下のように、関数の途中で現れる IDC_SOMOTHING に相当する 部分を引数としたいと思っています。 この場合、どのように記述すればよいのでしょうか。 戻り値 関数名(引数) {       ・       ・       ・ // デバイスコンテキストの獲得 CWnd* h = GetDlgItem(IDC_SOMETHING); CDC* pDC=h->GetDC();       ・       ・       ・ } 引数が文字列なら    戻り値 関数名(CString temp){}              ̄ ̄ ̄ ̄ ̄ ̄ とできますが、ID を引数にとる場合、どのように引数を記述したらよいのでしょうか。 教えていただけると幸いです。

  • | (or) を使った関数の引数の作り方

    たとえば、 MessageBoxの4つ目の引数のような感じで、 MessageBox(NULL, "本文","タイトル", MB_YESNO|MB_ICONQUESTION); の、 4つ目の引数が|(or)で引数の指定ができますが、 こういった関数を自分で作る場合に、 どのように関数作成して、 4つ目の引数は関数内でどのように取得していけばいいのでしょうか? 基本的なことなのかとは思うのですが・・・ 良い解説のあるHPなど、 ご教授いただきたく思います。 よろしくお願いいたします。

  • | (or) を使った関数の引数の作り方

    たとえば、 MessageBoxの4つ目の引数のような感じで、 MessageBox(NULL, \"本文\",\"タイトル\", MB_YESNO|MB_ICONQUESTION); の、 4つ目の引数が|(or)で引数の指定ができますが、 こういった関数を自分で作る場合に、 どのように関数作成して、 4つ目の引数は関数内でどのように取得していけばいいのでしょうか? 基本的なことなのかとは思うのですが・・・ 良い解説のあるHPなど、 ご教授いただきたく思います。 よろしくお願いいたします。

  • メモリアロケーション異常の発生方法

    こんにちは。 プログラムテストの仕様書を作成してます。 mallocの戻り値がNULLの場合の処理のテスト方法に迷っています。 指定したサイズのメモリが取れなかったときに、 mallocで異常(戻り値=NULL)になるということですので、 あらかじめメモリ不足状態を作るのかとも思うのですが、 方法がよくわかりません。 いいテスト方法があれば、教えてください。 宜しくお願いいたします。

  • スプレッドシートのGASの関数で複数戻り値取得

    googleのスプレッドシートを使っています。 Google Apps Scriptでデータの取得を行っているのですが、 1つの関数から複数の戻り値を得るような方法はありますでしょうか? マイコンのC言語などをやった際に、ポインタ変数を関数の引数に設定して、その関数の引数に配列変数などをアドレス指定で設定することで複数の戻り値を得るような方法があったと思うのですが、GASでも同様の方法などはありますでしょうか? どうぞ、ご教示の程よろしくお願い致します。

  • GCCで関数の引数が渡らない

    gcc Ver2.9 でSH-2の開発をしています。 通常に関数を作成し、引数を渡しているのですが、引数が渡らないという現象が起きています。 現象は、 1.引数はポインタではなく値渡しである 2.引数の値が0の時だけ正しく渡らない。値が0以外の時は正常にわたる 3.引数の型は一致している 4.引数は複数あるが、後半のいくつかがだめ(何個とまでは詳しく調べていません) 5.ある特定の関数の特定の呼び出しのみがだめで全てだめというわけではない 6.コンパイルオプションに -m2 をつけるとだめだが、-m1 オプションだと問題ない 7.最適化オプションをなくしても同じだった といった状況です。 上記5からある特定の記述方法とか順序になるとだめになるのではないかといろいろ試してみたのですが見つけられません。6から記述方法に誤りがあるとも考えにくい状況です。コンパイラのバグといって片付けていいものなのかどうかです。どなたか同じような経験をされた方はいらっしゃいませんか。また関数呼び出しの場合、コンパイラがどうやって引数を渡すかご教授願えませんか。

  • JNIを使った、全角半角が混在した文字列の引数、戻り値の受け渡し

    JNIを使用して、JavaからExcelを操作しようと考えております。 ワークブックを開くDLL関数を用意し、 その際に、引数としてファイルのフルパスを、戻り値として開かれたブックの名称を返すようにしたのですが、 半角英数の文字は正しく帰ってくるのですが、全角のファイル、及びフォルダを引数に指定した場合、 文字化けが発生し、ブックを開けず、困っております。 JNIを使った全角半角が混在した引数、戻り値の関数の受け渡しを行なうにはどのようにすればよいのでしょうか。 ご回答をよろしくお願いいたします。

  • $_POSTで受け取ったデータの挙動について

    PHP5.3を使用しています。そこで、 <?php $var1 = $_POST["var1"]; $var2 = $_POST["var2"]; $var3 = $_POST["var3"]; $var4 = ; // 誤った記述だがvar1~var3のどれかが代入される ?> 上のコードのサンプルにも入れましたが、このように記述すると受け取った引数うちのどれかが$var4に代入されるようです。私の環境では2番目の引数が代入されやすいようですが・・。 $_POSTはグローバル変数のはずですが、それを代入の右辺に用いていないのに値が代入されてしまうという挙動の原因をご存知の方がおられましたらご教授願います。そもそもエラーレポートをしている場合、上野記述はエラーとして出されるとは思いますが・・・

    • ベストアンサー
    • PHP

専門家に質問してみよう