C++ のセグメンテーション違反を修正
この記事では、C++ のセグメンテーション違反について説明し、この問題を解決するためのソリューションを提供します。
C++ のセグメンテーション違反
C++ のセグメンテーション違反は、プログラムまたはシステムが手の届かないメモリにアクセスしようとすると発生します。 これは、実行時にプログラムがクラッシュする一般的な状態です。
C++ でのセグメンテーション違反の原因の背後にある理由は、プログラムまたはシステムの制限を超えた不正なメモリ位置からデータを読み書きしようとすることです。
コード例:
#include <iostream>
using namespace std;
int main(void) { // This program will crash becasue it has segmentation fault
int *i = NULL;
*i = 10; // This line causes the error
cout << *i << endl;
return 0;
}
出力:
Segmentation fault
このプログラムでは、ステートメント *i =10;
*i
、NULL
を逆参照しているため、セグメンテーション違反が発生しています。 NULL
を変更しようとしていますが、これは許可されていません。 したがって、セグメンテーション違反があります。
C++ でのセグメンテーション違反の原因
通常、プログラム メモリはさまざまなセグメントに分割されます。
- テキスト セグメントは、プログラムのステートメントと命令に使用されます。
- データ セグメントは、コンパイル時に変数と配列の定義を担当します。
- スタックセグメントは、サブルーチンおよび関数で定義された一時変数 (ローカル変数) を担当します。
- ヒープ セグメントは、Fortran の
allocate
や C のmalloc
などの関数によって実行時に変数の割り当てに使用されます。
アクセス違反とも呼ばれるセグメンテーション違反の原因は、初期化されていないメモリへのアクセスと、制限を超えたデータの読み取りと書き込みです。 C++ でセグメンテーション違反が発生する一般的な理由の一覧を次に示します。
- 配列の無効なインデックスへのアクセス;
- NULL ポインターと解放されたメモリーの逆参照。
- 初期化されていないメモリの逆参照。
- アドレスの
&
および逆参照*
演算子の使用が無効です。 - スタック オーバーフロー。
- 読み取り専用メモリへの書き込み。
C++ のセグメンテーション違反を修正
C++ でこのようなセグメンテーション違反を回避するために、プレアクティブ戦略とプロアクティブ戦略の両方を使用してセグメンテーション違反を克服しました。 セグメンテーション違反を防ぐために使用できるいくつかのソリューションを次に示します。
解決策 1:
セグメンテーション違反を追跡およびデバッグするために実行できるいくつかの手順を次に示します。
- コードを
-go
でコンパイルします。 これにより、バイナリ ファイルにデバッグ シンボルが表示されます。 - 次に、
gdb
コマンドを使用して gdb コンソールを開きます。 - ファイルを使用して、コードのバイナリ ファイルをコンソールに渡します。
- 次に、アプリケーションを実行して引数を渡して開始します。
- セグメンテーション違反を引き起こすコードを使用します。
- 最後のステップは、
gdb
コンソールにbt
と入力して、障害のトレースを取得することです。
解決策 2:
プログラムのクラッシュが問題の本当の原因ではない場合もあります。 おそらく、以前の時点でメモリが破壊された可能性がありますが、破損が現れるまでに時間がかかりました. ポインタの初期化と割り当てを見てください。
解決策 3:
問題が発生する前に対処するようにしてください。 次のようなアクティブなエラー処理戦略を使用します。
- プログラム コードを頻繁にコンパイルして実行します。 障害を簡単に特定するのに役立ちます。
- メモリを直接操作することがほとんどない、低レベル/エラーが発生しやすいルーチンをカプセル化してみてください。
- テスト スイートを維持し、機能しているものと機能していないものを分析します。 これは、問題の場所を特定するのに役立ちます。
解決策 4:
ほとんどの問題はポインターにあり、正しく初期化されていないポインターを使用している可能性が非常に高いですが、二重解放でメモリ管理を台無しにしている可能性もあります。
また、初期化されていないポインターを避けるために、プログラムの最後と後半で宣言するようにしてください。ただし、これが常に可能であるとは限りません。 NULL
または 0
として初期化してみてください。
Zeeshan is a detail oriented software engineer that helps companies and individuals make their lives and easier with software solutions.
LinkedIn