2017-09-22 9 views
2

次のコードで解決したい問題は、あるサイズの整数配列を特定の数値シフトに回転させることです。例えば 、C++ポインタ:配列のスタックが壊れていた

int a[5] = {1,2,3,4,5} 

のためにどこsize =5shift = 2のために結果がでなければなりません

{3,4,5,1,2} 

は、これは私の関数である

void rotate(int a[], int size, int shift) 
{ 
    for (int i = 0; i < shift%size; ++i) { 
     int *buffer = &a[0]; 
     a = &a[1]; 
     int l = *buffer; 
     a[size - 1] = l; 
    } 
} 

出力は正しいですが、実行時例外があります

Stack around the variable 'a' was corrupted 

問題が

a[size - 1] = l; 

に間違いですが、私は正確に何が間違っている、理解することはできません。
ご協力いただきありがとうございます。

+0

これは既に存在します: 'std :: rotate' – chris

答えて

6

a = &a[1];だからa[-1]a[3]に包括1.

によってポインタaをシフトされ、有効なインデックスの範囲です:a[size - 1]はそれを違反しています。

このようにしてaを変更しないことをおすすめします。

0

バトシェバは既に述べたように、a = &a[1];は(++a;又はa++;と全く同じ効果を有する)割り当てa[size - 1] = l;は、すぐ隣の配列にメモリへの書き込み効果を有するポインタを移動させます。エラーが発生するかどうかは、rotateが呼び出されているコードによって異なります。私はちょうどmainと一緒にrotateを実行しましたが、エラーメッセージは表示されません(コンパイル中でも実行時でも)。

しかし、rotateは正しい出力を得られません。何も回転させることはありませんが、単に配列の一部を配列のすぐ隣のメモリに書き込みます。ちょうど何かが回転した場合、配列に十分な空きメモリがある場合(それ以外の場合は上書きされます)、rotateを呼び出すコードでも配列の開始アドレスを変更したようです。

void rotate(int a[], int size, int shift) { 
    for (int i = 0; i < shift%size; ++i) { 
     // buffer was superfluous 
     ++a; 
     // l was superfluous 
     a[size - 1] = a[-1]; 
    } 
} 

次のようにも、あなたのプログラムと全く同じ効果があります:

void rotate(int a[], int size, int shift) { 
    for (int i = 0; i < shift%size; ++i) { 
     a[size + i] = a[i]; 
    } 
} 
より良いプログラムは、私はまったく同じ効果がなといくつかのステートメントに置き換えられていないかを理解するには

これで、要求されたとおりに動作するようにアルゴリズムを変更する必要があることが簡単にわかります。

+0

あなたのコードは、配列の最初の数を最後まで押し込まずに配列をメモリに移動します。ですから、 "a [size - 1] = l;"で入力と出力に同じ行番号があります。私は以前に最初の数字を配列の最後に追加して、行を少し回転させます。しかし、私は同意します。この追加の変数 "L"は実際には必要ではなく、解決策は厳密に正しいものではありません。 – riverhare

+0

あなたのコードを理解しやすくするためにコードを書き直しました。これは**全く問題ではありません**。ポイントは:あなたのコード(上の質問に掲示されているように)**は私の答えのものとまったく同じ**です。これはループ内でポインタ 'a'を動かすだけでは容易に見ることができません。 – Fabian