重複の可能性:
実際の例による配列とポインターの類似点と相違点
以前は、配列名を参照して同じものとして使用していました。しかし今、エラーが発生しました。つまりint *path
、配列のメンバーを使用してアクセスしようとすると、コンパイラーは SIGSEGV を取得します (以前に書いたコードで発生したことを覚えていませんでした)。私が使用するときint path[]
。
では、使用時に SIGSEGV を取得するのはなぜint *path
ですか?
重複の可能性:
実際の例による配列とポインターの類似点と相違点
以前は、配列名を参照して同じものとして使用していました。しかし今、エラーが発生しました。つまりint *path
、配列のメンバーを使用してアクセスしようとすると、コンパイラーは SIGSEGV を取得します (以前に書いたコードで発生したことを覚えていませんでした)。私が使用するときint path[]
。
では、使用時に SIGSEGV を取得するのはなぜint *path
ですか?
宣言した配列に、同等ではない2つの可能な方法で書き込もうとしていると推測するだけです。
int *path = { 4, 5, 3, -1}; /* you're saying this does not work ... when? */
// ^ compiler "warning" (error) expected, see edit below
path[2] = 1; /* .. when you try this */
しかし
int path[] = { 4, 5, 3, -1};
path[2] = 1; /* but this works */
最初のケースでは、pathはどこかに置かれた「静的」「リスト」へのポインタです。あなたはそれへのポインタを持っており、コンテンツを読むことができますが、それを書き込もうとすると、セグメンテーション違反が発生する可能性があります。(おそらく、それらのデータは、頻繁に発生する場合でも書き込むことができるメモリにある可能性があるため、書き込むことはできませんが、システムによって異なります)。
2番目のケースでは、スタック上の領域が予約されており、データを保持するのに十分な大きさであり、データはその領域にコピーされます。この場合、読み取りと書き込みの両方を行うことができます。
編集
コメントで気づいたように、最初の例では警告が表示されます。警告なしでコンパイルするには、キャスト(int [])が必要です。次に、書き込みできない場所に配列が作成されたとしましょう。ただし、そうではありませんでした。
int *path = { 4, 5, 3, -1};
上記を実行すると、データは読み取り専用メモリに格納されます。したがって、そのポインタを使用してインデックスを変更しようとすると、sigsegvが取得されます。
しかし、あなたがするとき
int path[]={...};
読み取り専用ではない静的メモリに格納され、配列内のデータを変更できます
int path[]
: パス ポイントの実配列int *path
: パスは単なるメモリ ポインタです。のメモリ位置は、path
実際の配列を保持していない可能性があります。で試しmktemp()
ているに違いありませんchar *path
。私は何度もやったことがあります。:-( この SEGV の理由は他の人によって説明されています。
ありがとう。