2012-03-21 12 views
0

私のCコードで助けが必要です。私は、あなたが関数に入力した値にメモリ の場所に値を設定する関数を持っています。C言語でメモリに問題があります*

私が直面する問題は、ポインタが割り当てられたメモリ量を超えて移動する場合です。 エラーが発生するはずです。この問題を確認する方法がわかりません。

unsignded char the_pool = malloc(1000); 
char *num = a pointer to the start of the_pool up to ten spots 
num[i] = val; 
num[11] = val; //This should throw an error in my function which 

どのように私が不正なメモリ空間に移動したかを確認するにはどうすればよいですか。

+3

これはコンパイルされず、バッファをオーバーランさせないようにする方法は、サイズを記録することです。 – Joe

+0

申し訳ありませんが、私はすべてを提供しませんでした。私は私が演奏する大きなメモリプールを作成しています。私は小さなチャンクへのポインタを値に設定します – jenglee

答えて

3

Cはこのエラーを検出しません。あなたは自分でそれをしなければなりません。

たとえば、あなたは安全機能であなたの配列へのアクセスをラップすることができます:

typedef struct 
{ 
    char *data; 
    int length; 
} myArrayType; 

void MakeArray(myArrayType *p, int length) 
{ 
    p->data = (char *)malloc(length); 
    p->length = length; 
} 

int WriteToArrayWithBoundsChecking(myArrayType *p, int index, char value) 
{ 
    if (index >= 0 && index < p->length) 
    { 
     p->data[index] = value; 
     return 1; // return "success" 
    } 
    else 
    { 
     return 0; // return "failure" 
    } 
} 

は、その後、あなたの書き込みが成功したかどうかを確認するためにWriteToArrayWithBoundsChecking()の戻り値を見ることができます。

完了したら、myArrayType->dataで指摘されているメモリをクリーンアップすることを忘れないでください。そうしないと、リークが発生します。

1

標準では、Undefined behaviorと定義されています。それがうまくいくかもしれない

は、それは、あなたが知っていることはありません、C/C++でコーディングするとき、あなたの配列にアクセスする前に必ず境界をチェックします

3

はあなたが意味いけないのでしょうか?

num[11] = val 

はい、自分で行う以外は境界を超えているかどうかを確認する方法はありません.Cはこれを行う方法はありません。また、配列はゼロから始まるので、num [10]も境界を超えていることに注意してください。

+0

はい私はnum [11] = valを意味しました、私は謝ります – jenglee

-1

Visual Studio 2010(または2011 Beta)を使用している場合、割り当てられたメモリを解放しようとすると、それまで通ります。

漏れたメモリをチェックするための高度なツールがあります。

例では、実際には許可されていないメモリ領域に実際に移動しています。あなたのインデックスは0〜(含む)999の間でなければなりません。

0

一般的なCコンパイラは、あなたのために配列境界チェックを実行しません。

Some compilers are available that claim to support array bounds - 通常、通常のコンパイラと比較して性能は劣りますが、通常はそれほど広く配布されていません。

There are even dialects of C intended to provide memory safetyしかし、これらは通常、あまり大きくはありません。 (リンクされているサイクロンは、例えば、32ビットプラットフォームしかサポートしていませんが、最後に調べました)

あなたが望むなら、境界チェックを提供する独自のデータ構造を構築することができます。データの先頭へのポインタ、割り当てられたサイズを含むデータメンバ、および構造体で機能する関数を含む構造体を維持する場合は、このすべてを実装できます。しかし、これらのデータ構造を提供するためには、あなたやあなたの環境全体に負担がかかります。

0

私はsizeofを使用して、配列アクセスがバインドされていないインデックスを避けることができると思います。しかし、cでは配列にバインドされているメモリからアクセスすることができます。それはcコンパイラにとっては問題ありません。あなたがそうしたときにOSはその動作を管理します。 C/C++では実際に配列に関して境界チェックは行われません。有効なメモリにアクセスしているかどうかは、OSによって異なります。 このように配列を使用できます。 型名[サイズ];

関連する問題