4

私は2010 CWE/SANS Top 25 Most Dangerous Programming Errorsを読んでいましたが、エントリの 1 つはBuffer Copy without Checking Size of Inputです。この問題を防止または軽減する機能を備えた言語を使用することを提案し、次のように述べています。

たとえば、Java や Perl など、独自のメモリ管理を行う多くの言語は、バッファ オーバーフローの影響を受けません。Ada や C# などの他の言語では通常、オーバーフロー保護が提供されますが、プログラマは保護を無効にすることができます。

メモリ管理に関して、Java と C# が意味のある点で異なることを知りませんでした。Java はバッファ オーバーフローの影響を受けないのに、C# はオーバーフローからのみ保護するのはなぜですか? また、C# でこの保護を無効にするにはどうすればよいですか?

4

2 に答える 2

5

Java は生のポインターをサポートしていません (厳密に言えば、ポインター演算はサポートしていません)。

C# では、アンセーフ コードとポインター、およびアンマネージ メモリを使用できます。これにより、バッファー オーバーランが可能になります。安全でないキーワードを参照してください。

型の安全性とセキュリティを維持するために、C# は既定ではポインター演算をサポートしていません。ただし、unsafe キーワードを使用すると、ポインターを使用できる unsafe コンテキストを定義できます。ポインターの詳細については、トピック「ポインター型」を参照してください。

于 2010-03-17T03:25:26.723 に答える
5

良い答え。Java は、スタックまたはヒープ メモリ ロケーションの使用に依存していることを付け加えておきます。C# も同様です。生のポインターを使用するというアイデアは、C コードのバックグラウンドに由来する C# への追加です。C# と C / C++ は同じコード言語ではありませんが、いくつかの共通点のセマンティクスを共有しています。「安全でない」コードを使用するという考え方により、ガベージ コレクションによる劇的なパフォーマンスの低下を招くことなく、ランタイム インスタンスごとに (C# の場合は CLR ごと、Java の場合は JVM インスタンスごとに) メモリが約 2GB に制限されているヒープに大きなオブジェクトを保持することを回避できます。場合によっては、C# の機能を使用して、安全でないまたは手動で管理されたメモリ ポインターを利用して、ヒープ外のキャッシュなどの問題に対応するサード パーティ ツールがそれほど多くないという事実を回避できます。

安全でないコードを使用する場合は、必ず「使い捨てタイプ」と「ファイナライザー」に慣れてください。これはかなり高度な方法である可能性があり、オブジェクトを適切に破棄しない場合の影響は、C コードの場合と同じです...恐ろしいメモリ リークです。影響は、アプリのメモリが不足し、失敗することです (良くありません)。そのため、C# では既定で許可されておらず、手動で制御されたポインターの使用を "unsafe" キーワードでオーバーライドする必要があります。これにより、手動で処理されたメモリが意図的なものであることが保証されます。「安全でない」キーワードを扱うときは、C コードの帽子をかぶってください。

これについては、Andrew Troelsen による「Pro C# 2010 と .Net プラットフォーム」の「オブジェクトの有効期間について」の章が参考になりました。オンライン リファレンスを希望する場合は、MSDN Web サイトの実装のファイナライズと破棄を参照して、管理されていないリソースをクリーンアップします。

最後に 1 つ - アンマネージ メモリは、オブジェクトのファイナライザー部分 (~ObjectName(){...}) で解放されます。これらのパターンはパフォーマンスにオーバーヘッドを追加するため、低レイテンシのシナリオを扱っている場合は、オブジェクトを軽量に保つことが最善の方法です。人間の反応を扱っている場合は、絶対に必要な場合にこれを考慮しても問題ありません。

于 2012-03-20T10:02:04.650 に答える