-4

私は立ち往生しており、これが次のコードの一部が実行されていない理由を理解できません。私はc/c ++にかなり慣れていません。

#include <iostream>
int main(){
    const char *arr="Hello";
    const char * arr1="World";

    char **arr2=NULL;
    arr2[0]=arr;
    arr2[1]=arr1;

    for (int i=0;i<=1;i++){
        std::cout<<arr2[i]<<std::endl;
    }
    return 0;
}

これは完全に正常に動作しているため

#include <iostream>
int main(){

    const char *arr="Hello";
    const char * arr1="World";

    char *arr2[1];
    arr2[0]=arr;
    arr2[1]=arr1;

    for (int i=0;i<=1;i++){
        std::cout<<arr2[i]<<std::endl;
    }
    return 0;
} 

どうしてこれなの?一般的に、char ** を反復処理する方法は? ありがとうございました

4

4 に答える 4

3

char *arr2[1];「charへのポインタ」タイプの1つの要素(スタックに割り当てられている)を持つ配列です。arr2[0]その配列の最初の要素です。arr2[1]未定義です。

char **arr2=NULL;「charへのポインタ」へのポインタです。スタックにはメモリが割り当てられていないことに注意してください。arr2[0]未定義です。

結論として、どちらのバージョンも正しくありません。2番目のバリアントが「完全に正常に実行されている」ということは、バグのあるコードが正しく実行されているように見える可能性があることを思い出させてくれます。

編集:コード内のさらなる「違反」:

  1. 文字列リテラルはタイプchar const *であり、忘れないでくださいconst
  2. 関数のコードをインデントするのが一般的な(そして推奨される)方法です。
  3. 読みやすさを向上させるために、さまざまな場所にスペースを追加することをお勧めします(たとえば、post (、pre )、pre、postの二項演算子、ステートメント;内のpostなど)。for好みは異なり、可能な限りスペースを省くことを実際に奨励する声の派閥がありますが、あなたはそれを一貫して行っていませんでした-そして一貫性 普遍的に推奨されています。astyleのようなコードリフォーマッターを試して、読みやすさのために何ができるかを確認してください。
于 2012-07-23T07:13:22.980 に答える
1
char **arr2=NULL;

NULLを指すポインタへのポインタです

char *arr2[1];

は、2つのアイテムにすでにスペースが割り当てられているポインターの配列です。

ポインタへのポインタの2番目のケースでは、存在しないメモリ位置にデータを書き込もうとしていますが、そもそもコンパイラは配列に2つのメモリスロットを割り当てているため、2つに値を割り当てることができます。要素。

非常に単純に考えると、Cポインタは整数変数にすぎず、その値は実際にはメモリアドレスです。したがって、定義することによりchar *x = NULL、実際には値がNULL(つまりゼロ)の整数変数を定義していることになります。ここで、次のようなものを作成するとします*x = 5。これは、x(NULL)内に格納されているメモリアドレスに移動し、そこに5を書き込むことを意味します。アドレス0のメモリスロットがないため、ステートメント全体が失敗します。

正直なところ、私が最後にそのようなものを扱わなければならなかったのは何年も前のことですが、ここでのこの小さなチュートリアルは、C++での配列とポインターの動きをクリアするかもしれません。

于 2012-07-23T07:25:59.820 に答える
1

arr2 は何も指していないため、これは正しくありません。

char **arr2=NULL;
arr2[0]=arr;
arr2[1]=arr1;

正しい方法:

char *arr2[2] = { NULL };
arr2[0]=arr;
arr2[1]=arr1;

これも間違っています。arr2 のサイズは 1 です。

char *arr2[1];
arr2[0]=arr;
arr2[1]=arr1;

正しい方法は同じです:

char *arr2[2] = { NULL };
arr2[0]=arr;
arr2[1]=arr1;
于 2012-07-23T07:11:20.770 に答える
0

簡単に言えば、ポインタの宣言はメモリを予約しませんが、配列の宣言は予約しません。

最初の例では、行char ** arr2 = NULLは文字のポインターへのポインターを宣言していますが、値を設定していません。したがって、ゼロバイト(NULL == 0)を指して開始されます。あなたがarr2[0]=あなたがあなたに属していないこのゼロの場所に値を配置しようとしている何かを言うとき-したがってクラッシュ。

2番目の例では、宣言* arr2 [2]は2つのポインター用のスペースを予約しているため、機能します。

于 2012-07-23T07:13:12.383 に答える