3

構造体へのポインターの配列を理解できません。この簡単な例を作成して、それらをよりよく理解しようとしました。コンパイルはできますが、以下に示すポイントで「BAD ACCESS」クラッシュ (意味のないポインター) が発生し続けます。なぜこれが間違っているのか説明できる人はいますか?

#include <iostream>
using namespace std;

struct complex_num {
    double real_part;
    double imag_part;
};

void init_complex(complex_num *element) {
    element->real_part = -1.0;             // <--- EXECUTION STOPS HERE.
    element->imag_part =  1.0;
}

int main(int argc, char *argv[]) {
    int n = 5;

    complex_num *array[n]; // Allocates for an array of n pointers to
                           // the complex_num structure, correct?

    for (int i = 0; i < n; i++) {
        init_complex(array[i]);
    }

    return 0;
}

これを行うためのより良い方法があることを知っています。私はこれが非常にCスタイルであることを知っています。別のデータ構造を提案しないでください。特に構造体へのポインタの配列に興味があります。ありがとう!

4

2 に答える 2

4

complex_numオブジェクトへのポインターを持つ配列に対してのみ、オブジェクトにメモリを割り当てませんでした。そのため、init_complex を呼び出すと、無効な場所へのポインターが操作されます。

これを試して:

for (int i = 0; i < n; i++) {
    array[i] = new complex_num();
    init_complex(array[i]);
}

このステートメントcomplex_num *array[n]は、complex_num への n 個のポインターの配列を作成します。つまり、配列はcomplex_num へのn ポインターを保持できます。ただし、ポインター自体はまだ初期化されていません。それらはランダムな場所を指します-C++の初期化されていないすべてのプリミティブ(ポインターも属する)には、通常、割り当て前のメモリ位置にあった値が含まれます。初期化されていないポインターがどこを指しているかを知る方法がない (または少なくとも合理的に簡単な方法がない) ため、これはほぼ確実に予期しない結果につながります。

したがって、配列内の各ポインターが、適切に設定されたメモリ位置を指すようにする必要がありますcomplex_num。その後complex_num、ポインターが指す場所の値にアクセス (読み取りまたは書き込み) する必要があります。たとえば、動的に割り当てられた新しい complex_num オブジェクトを指すようにするには、上記のコードを使用します (new動的割り当てを行うキーワードに注意してください)。

補足: 上記のように、動的に割り当てられたオブジェクトを指す「Raw」ポインターは扱いが難しいため (delete終了後に呼び出すことを忘れないでください。そうしないと、メモリ リークが発生します)、通常は smart を使用することをお勧めしますポインター (C++11 で導入された std::shared_ptr など)。

于 2013-10-15T06:14:37.570 に答える