この質問にはすでに答えがあります:
クラッシュまたは「セグメンテーション違反」データが初期化されていないポインタにコピー/スキャン/読み取られたとき
(答えは5つ)
3 年前
に閉店しました。
私の関数は整数ポインターも返します。私は配列名が単なる整数ポインターであるという印象を持っていたので、次のように宣言しましたt.ポインターを反転する reverse() という関数を作成しました。これを gcc バージョン 7.5 を備えた ubuntu 18.04 で実行すると、セグメンテーション フォールト コア ダンプが発生します。これはなぜですか? また、これに対する正しくて最も効率的なコードは何ですか?
#include <stdio.h>
int * reverse(int * array, int n){
int * rev;
int i = n - 1;
int j = 0;
while(i >= 0){
rev[j] = array[i];
j++;
i--;
}
return rev;
}
int main(){
int array[] = {1,2,3,4};
int * p; //the pointer p that im declaring
p = reverse(array, 4); //i think this is the segmentation error
int i = 0;
printf("the first element is %d", p[0]);
}
3
int * rev; rev[j] = 配列[i]; rev は初期化されていないポインタであるため、未定義の動作になります。
– ケイラム
2020 年 9 月 3 日 11:47
3
コンパイラの警告を有効にします。 -Wall -Wextra を使用すると、問題が説明されたでしょう
– クルット
2020 年 9 月 3 日 11:48
ああ、はい、ありがとうございます!
– ザーヒル・アハメッド
2020 年 9 月 3 日 11:51
1
ところで、このような場合に何が起こるかを調べる最も効率的な方法は、デバッガを使用することです。使い方を学べば、数え切れないほどの時間を節約できます。
– ジャバウォッキー
2020 年 9 月 3 日 11:52
1
"_ 配列名は単なる整数ポインタであるという印象を受けていました_"その印象は間違っています。関数に渡されたときなど、場合によっては配列名がポインタに変化しますが、それらは大きく異なります。NG。配列名にはサイズ情報がありますが、ポインタはサイズ情報を失います。また、当然ながら、要素が別の型である場合、それは int[] や int* にはなりません。
– underscore_d
2020 年 9 月 3 日 11:59
------------------------
"ポインタを反転する reverse() という関数を作成しました。これを gcc バージョン 7.5 を搭載した ubuntu 18.04 で実行すると、セグメンテーション フォールト コア ダンプが発生します。これはなぜですか?
逆方向のポインタ rev はメモリを指しません。 rev を参照解除する前に、n * sizeof(int) のメモリを割り当て、そこを指すポイントに rev を割り当てる必要があります。そうしないと、未割り当てのメモリにアクセスする未定義の動作が発生します。
int * rev = malloc( n * sizeof(int) );
if (!rev)
{
perror("malloc");
// error routine.
}