2011-03-10 18 views
1

私はC/C++でコーディングしています。データセグメントに格納されている静的変数を破損させる可能性のある方法は何ですか?これはメモリリークと見なされますか?Linuxプロセスのデータセグメントを壊す方法はありますか?

#include <stdio.h> 

int aaa[5]; 
int bbb; 
int main() 
{ 
     int i; 
     bbb=41; 
     for (i = 0; i < 6; ++i) 
       aaa[i] = 42; 
     printf("%d\n", bbb); 
     return 0; 
} 

上記のコードは、bbb = 42であり、41ではありません。これは考えられる原因です。別の方法は、複数のスレッドを介してアクセスされる静的データを に変更することです。

他の方法はありますか?

+2

CまたはC++?どちらも完全に異なる言語です。 –

+0

C++です。 C – cateof

答えて

1

はい、(あなたの変数はあなたが投稿の例では静的ではありません)グローバル変数の内容を破壊するために複数の方法があります。

ポインタは、メモリを破壊し、プログラムがどこに書き込まれてはならないかを示す良いツールです。 、あなたは、それらが値をリードバックしている、グローバル変数に各スレッドの書き込みを持つことができ、複数のスレッドで

#include <iostream> 
using namespace std; 

int aaa[5]; 
int bbb; 

int main(void) // Do *your* main() functions always return a value???? 
{ 
    double * ptr_double = 0; 
    // Assign the pointer to double to point to the last integer. 
    // Treat the last integer in the array as a double. 
    aaa[4] = 45; 
    cout << "aaa[4] = " << aaa[4] << endl; 

    ptr_double = (double *)(&aaa[4]); 
    *ptr_double = 3.14159267; 
    cout << "aaa[4] = " << aaa[4] << endl; 

    return -1; 
} 

:鋳造にもいくつかの興奮を追加することができます。執筆の前に、そして執筆の後に、ランダム遅延を置くことで、それがどのように働くかをより詳細に示すことができます。

もう1つの方法は、変数のアドレスをI/Oハードウェアデバイスの宛先レジスタ(UARTなど)に割り当てることです。 UARTがデータを受け取ると、そのデータはその変数の目的に関係なく、その変数に配置されます。

一般的に、値はコードの書き込みによって崩壊してはなりません。主な原因は、バッファオーバーランです。変数に割り当てられているより多くのデータを書き込んでいます。オーバーランは、DMAコントローラやUSBコントローラなどのハードウェアデバイスから発生することもあります。もう1つの原因はポインター経由です:ポインターが無効な場所を指しています。

スタックオーバーフローとヒープオーバーフローによって変数が壊れる可能性があります。多くのアーキテクチャでは、これらの構造は互いに向かって展開します。スタック上の変数が多すぎたり、関数の再帰(または呼び出し深度)があると、スタックがヒープに上書きされる可能性があります。同様に、ヒープからあまりにも多くのメモリを割り当てると、ヒープがスタックに上書きされる可能性があります。

変数を破損する方法を調べるのではなく、コードの安全性を向上させるために作業する必要があります。バッファオーバーランが発生しないようにコードを作成し、正しい場所に書き込んで共有変数を複数のタスクスレッド。

4

いいえ、これはメモリリークではありません。メモリリークは、フリーストア(malloc/new)に割り当てた後、割り当てられたブロックであるfree/deleteを決して使用しない場合です。これは未定義の動作が保証されていないことを

2

注:この特定のケースのBBBに

int bbb; 
int aaa[5]; 
int main() 
{ 
    int i; 
    bbb=41; 
    for (i = 0; i < 6; ++i) 
      aaa[i] = 42; 
    printf("%d\n", bbb); 
    return 0; 
} 
g++ -o test test.cpp && ./test 
41 

は、AAA後に保存されているが、それはどこか別の場所かもしれない原因あなたは、このすべてに頼るべきではありません。

+0

ではありません静的なグローバル変数を破損する他の方法はありますか? – cateof

+0

静的グローバル変数を破損する保証された方法はありません。あなたがしようとしているものが多少既存のコードをハックするのであれば、静的なvarを自分で登録し、静的な変数のメモリアドレスの上下にいくつかのバイトのゴミを書き込もうとします。 –

+0

スタックやヒープのバグが.dataを壊す可能性がありますか? – cateof

1

すべてのグローバル変数は、プロセス内のコードを実行する前に、宣言で指定された値(または指定されていない場合はゼロ)に初期化されます。デフォルト値は、プロセス内で実行されるコードによってのみ変更されます(デバッガからの外部干渉を除く)。

プログラムのmain()関数の先頭に「破損」値が表示されている場合は、グローバルC++オブジェクトのコンストラクタ内で実行された操作が不適切である可能性があります。すべてのグローバルC++オブジェクトのコンストラクタは、main()の呼び出しの前に実行されます。

この種の破損の原因を突き止める最も簡単な方法は、おそらくプロセスをデバッガで実行し、グローバル変数のアドレスにウォッチポイントを設定することです。デバッガは、データが変更されると中断します。あなたは、配列のオーバーランや誤ったポインタの問題がありますか?彼らは手動で追跡することができます。

1

これは一般的なプログラミングエラーです。 aaa [0]、aaa [1]、aaa [2]、aaa [3]、およびaaa [4]のみ使用できる6つのaaaを使用している間、aaaの配列の5つの項目を定義します。 aaa [5]は定義されていません。 これはバグ、プログラミングエラー、その他何もありません。期間。

関連する問題