配列 - 整数ポインター p を宣言し、それを関数の戻り値に代入すると、セグメンテーション違反が発生するのはなぜですか?

okwaves2024-01-25  8

この質問にはすでに答えがあります: クラッシュまたは「セグメンテーション違反」データが初期化されていないポインタにコピー/スキャン/読み取られたとき

(答えは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.
}

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。