19

Linuxman shmatからの逐語的' :

戻り値

[...]エラー時(void *)-1が返され、エラーの原因を示すためにerrnoが設定されます。

(POSIXは、わずかに異なる表現を使用して同じことを伝えます。)

(void *) -1有効なアドレスではない可能性のある必須のルールまたは定義(標準?)はありますか?

4

3 に答える 3

19

0xffffffffは技術的には32ビット環境では有効なアドレスですが、ほとんどのオペレーティングシステム(確かにLinux / Windows)では、アドレス空間の予約済みカーネル部分にあります。つまり、ユーザーモードのプロセスでは、ユーザーモードの割り当て関数がこれを使用可能なアドレスとして返すことはないため、エラーコードとして使用しても安全です。

于 2012-11-09T11:12:14.030 に答える
14

簡単にするために、16ビットのアドレス空間を持つマシンを考えてみましょう。このマシンは、0から65535までのメモリをアドレス指定できます。この場合、65535(void*) -1である0xffffと同じになります。技術的にはこのアドレスは有効ですが、アクセスを許可するものがそこにあるシステムはほとんどありません。

考慮すべきもう1つのことは、ほとんどすべてのPOSIXシステムコールが-1エラー時に返されることです。


Benjが指摘したように、実際にはアドレスをマップすることは可能NULLです。これは、たとえば、指定されたマッピングがあるかどうかを確認する場合に使用できますshmid。この場合、shmaddr引数はに設定されNULL、関数NULLは共有メモリが存在することを示すために戻ります。

于 2012-11-09T11:10:41.673 に答える
12

質問に直接答えるために、いいえ、(void *) -1有効なアドレスではない可能性があるという必須の規則、定義、標準、または仕様はありません。

(もちろん、メモリアドレスに関する規則、定義、標準、仕様は必須ではありません。たとえば、C標準に準拠せずに毎日通りを歩いている人を見かけますが、逮捕された人を見たことがありません。しかし、必須部分を省略しても、(void *) -1一般的な仕様ではアドレスとしての使用は一般的に禁止されていません。)

(void *) -1ただし、 shmatが機能するために、有効なアドレスである必要はありません。shmatの呼び出しが成功し(void *) -1ても戻らないこと、および(void *) -1shmatからの戻り値をテストする目的でコンパイラーによってサポートされていることが必要なだけです。これらの2つの条件が満たされている場合、プログラムは常に成功したshmat呼び出しと失敗したshmat呼び出しを区別できます。

2番目の条件に関しては、C標準は(void *) -1使用できることを保証しないため、POSIXは、これがshmatからのエラー戻りであることを指定する際に、C(または他の言語)実装がそれをサポートすることを暗黙的に要求します。したがって、これはPOSIXで必要な言語の拡張であり、通常、コンパイラーがサポートするのは簡単なことです。

(void *) -1最初の条件に関しては、呼び出しが成功するためにshmatがいつ戻るかを検討してください。shmatは、ユーザーが要求したアドレスを使用して、または使用せずに呼び出すことができます。その場合、実装はアドレスを選択します。通常のコンピュータアーキテクチャでは、さまざまな値の倍数であるアドレスを使用する理由は複数あります。shmatの場合、最も明白なのはメモリマッピングです。仮想メモリを備えたアーキテクチャでは、メモリはページ単位でマップされ、shmatは、セグメントのメモリをマップするときに、ページの先頭にマップされます。偶数のページサイズには倍数がありません(void *) -1。後者は奇数であるため、shmatはセグメントをにマップすることを選択しません。(void *) -1。shmatがページサイズを使用しなかった場合でも、通常は4、8、16バイトなどの他の配置を使用します。これは、配置されたメモリを提供すると、そのメモリの先頭に格納されている構造が配置され、メモリが高速になるためです。多くのプロセッサへのアクセス。

それは、ユーザーがアドレスとして要求する場合を残し(void *) -1ます。これは異常であり、メモリセグメントが1バイトであるか、メモリモデルがラップアラウンドを許可されている場合(またはコンパイラ(void *) -1がアドレス空間の最後のバイトではない非常に奇妙なメモリモデルを提示した場合)にのみ機能します。POSIXシステムがこれをサポートしているかどうかは定かではありません。しかし、これは本質的に役に立たないことは明らかであり、好奇心以外にそれを行う理由はありません。したがって、このケースをshmatから除外することは安全で合理的​​であり、単にサポートされていないと言って、それを行わないでください。

于 2012-11-09T14:14:47.087 に答える