2

次のコードがあるとします。

#include<iostream>
int main(){
  char container[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
  for(char* cptr = container; *cptr != 0; cptr++)
    std::cout << *cptr << std::endl;
  return 0;
}

実行するたびに、これらの文字を順番に出力します。コンテナー配列の末尾に null ターミネーターを明示的に指定していないため、ループが終了する理由がわかりません。助けてください。

4

4 に答える 4

8

本当にただの運です。

たまたま に対応するメモリの領域container[7]が 0 になっているので、ラッキーです。

配列の境界を超えることは、未定義の動作です。あなたの場合、それはたまたまあなたが望んでいた動作ですが、それに頼ることはできません。

于 2013-10-14T16:43:12.407 に答える
3

まず、投稿したコードには恐ろしいバグcptr != 0があります*cptr != 0。ポインター自体が null かどうかではなく、指定されたアドレスの文字が nullかどうかを確認する必要があります。

他の回答とコメントは正しいです。正しい出力が得られる唯一の理由は、コンテナ配列の最後にメモリがゼロになっているためです。構造体内にcontainer配列を配置すると、コンパイラが挿入する可能性のある余分なパディングを排除するのに役立ちます。

#include<iostream>
int main(){
  struct {
    char container[7];
    char alphabet[27];
  } x = {
    {'a', 'b', 'c', 'd', 'e', 'f', 'g'},
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  };
  for(char* cptr = x.container; *cptr != 0; cptr++)
    std::cout << *cptr << std::endl;
  return 0;
}

このバージョンを実行すると、配列'a'–<code>'g' が出力され、2 番目の配列に実行されて'A'–<code>'Z' が出力されてから、その文字列の最後に null が表示されます。

于 2013-10-14T17:01:33.993 に答える
2

未定義の動作を引き起こす配列の終わりから実行しています。考えられる未定義の動作の 1 つは、一見合理的な方法で動作することです。この場合、未定義の動作により配列にゼロが埋め込まれている可能性があります。

于 2013-10-14T16:43:24.827 に答える
1

あなたは未定義の行動を引き起こしています。未定義の動作とは、「何でも起こり得る」ことを意味し、場合によっては、まさにあなたが望んでいることも含まれます。それがここで起こっていることです。

Undefined Behavior を呼び出す理由は、 の 1 つ後ろの要素にアクセスするときに、初期化されていないメモリから読み取っているためですcontainer

于 2013-10-14T16:48:41.760 に答える