2016-05-09 3 views
0

いいえ、非常に基本的な質問ですが、私はそれに固執しています。私は配列の終わりに余分な神秘的な値を把握することはできません。私はちょうどその基本アドレスを使って配列を横断しようとしました。しかし、配列の最後のガベージ値は、実行するたびに一定のままです。余分な要素を与えるポインタで配列にアクセスする

g ++コンパイラ64ビットマシン。

#include<iostream> 
#include<bits/stdc++.h> 

using namespace std; 

void printarray(int * arr){ 
    while(*(arr)){ cout<<*arr<<" "; arr++; } 
    cout<<endl; 
} 

int main(){ 
    int arr[] = { 3,2,4,1,5 }; 
    printarray(arr); // prints 3,2,4,1,5,32765 
    return 0; 
} 

EDIT 1:whileは、配列の0を渡ったときに終了するか、0が見つからないときには異常終了することを理解しています。しかし、それでもまだ、私はあなたたちには、次のテストケース

を見てみたいと思う
3,2,0,4,1,5 // outputs 3,2 
3,2,4,1,5,7,8,9 // outputs same array correctly 
3,2,4,1,5,7,8,9,10 // outputs array+ 1 varying garbage at last 

//observations, this method works for even sized arrays not containing    
//0, while for odd it emits an additional garbage value. 

中のみ0で破った場合私の質問は、なぜそれが
にarrayLength + 1毎回で壊れるんですか?この奇妙な長さには何がありますか?

+1

statement by statementをデバッグしましたか? –

+0

while(*(arr)) 'なぜこれを使用しますか?配列の最後に到達した時点で、それはすでに遅すぎて、あなたのコードはまだ狂った不思議の国(別名未定義の動作)になっています。 – user463035818

+1

'while(*(arr))'はゼロ終了配列を期待していますが、 。次の任意の0が見つかるまで、範囲外の配列にアクセスしています。 –

答えて

5

配列は特別な方法で終了されません。 while(*arr)は、配列末尾に0要素がありますが(sentinel)、配列は{3,2,4,1,5}と宣言しているため、末尾の要素は存在しないという誤った仮定に基づいています。 は、++arrでインクリメントしたときはいつも、sizeof(int)で調節しているということになります。それ以上のことは、配列の最後に到達すると、アドレスは配列の後ろを指しています。

1

配列は関数に渡されるとポインタに崩壊し、この関数は配列の長さについて何も知らない。

これはwhile(*arr)が間違っています。このポインターが指している値の一部がの場合にのみ、が停止します。しかし、誰がゼロは、配列の最後に配置されていると言った??あなたがarrをインクリメントすると、簡単にあなたの配列の境界から出ることができます(関数はそのサイズを知らない)!*arrは、メモリアドレスarrが現在ポイントしているものが何であれ、あなたに与えます。

配列全体を反復処理するには、配列自体とその長さを渡します。それ以外の場合は、*arrの値がゼロになるまで繰り返されます。

2

ポインタが指し示す要素の数をコンパイラに指示するポインタがないため、余分な要素があります。実行したとき

while(*(arr)){...} 

whileループは、*arr == 0まで実行を継続します。配列には0が含まれていないので、0が見つかるまで配列の最後を過ぎて進みます。このポインタで所有していないメモリにアクセスしているとき、これは未定義の動作です。

char配列(c-strings)が他のデータ型と比較してどのように動作するのか混乱するかもしれないと思います。あなたは

char arr[] = "something"; 
while(*(arr)){...} 

を持っている場合は、C-文字列がnullターミネータを取得し、これは、配列の終わりで終了(0)自動的に文字列の末尾に追加。これにより、ヌルターミネータがそこにあることを知っているように、上のループのようなことをすることができます。そうでない場合は、文字列を作成した人にそれがあります。

0

ポインタはC++で任意の文字で終了しません。 これは、\0(0)で終了しているため、char*などの他のタイプでのみ機能します。

アンINT-アレイuはあなたがあなたのポインタから終了5と、ここで例えば、そのような何かにそれらを渡すことができます前に、要素をカウントする必要があります。

#include <iostream> 
#include <bits/stdc++.h> 
using namespace std; 
void printarray(int * arr){ 
    int *saved=arr; 
    while(*saved!=5) 
    { 
    cout<<*saved++<<" "; 
    } 
    *saved=0; 
    cout<<endl; 
} 

int main(){ 
    int arr[] = { 3, 2, 4, 1, 5 }; 
    printarray(arr); // prints now without ending 5. 
    return 0; 
} 

そうでない場合は、あなたがカウンターに合格する必要があります要素の ポインタが指す要素の数をC++が知る方法はありません。

関連する問題