web-dev-qa-db-ja.com

関数からポインターを返す

関数からポインタを返そうとしています。しかし、セグメンテーション違反が発生しています。誰かがコードの何が悪いのか教えてください

#include<stdio.h>
int *fun();
main()
{
    int *ptr;
    ptr=fun();
    printf("%d",*ptr);

}
int *fun()
{
    int *point;
    *point=12;  
    return point;
}   
32
user567879

ポインタを使用する前にメモリを割り当ててください。メモリを割り当てない場合*point = 12は未定義の動作です。

int *fun()
{
    int *point = malloc(sizeof *point); /* Mandatory. */
    *point=12;  
    return point;
}

また、printfが間違っています。逆参照する必要があります(*)ポインター。

printf("%d", *ptr);
             ^
47
cnicutar

ローカルオブジェクトへのポインタを返すことは悪い習慣ですが、ここではkaboomを引き起こしませんでした。セグメンテーション違反が発生した理由は次のとおりです。

int *fun()
{
    int *point;
    *point=12;  <<<<<<  your program crashed here.
    return point;
}

ローカルポインターは範囲外になりますが、実際の問題は、初期化されなかったポインターを逆参照することです。ポイントの価値は何ですか?知るか。値が有効なメモリ位置にマップされなかった場合、SEGFAULTを取得します。幸いなことに、それが有効なものにマッピングされた場合、その場所を12に割り当てて上書きすることにより、メモリを破損しただけです。

返されたポインターはすぐに使用されたため、この場合、ローカルポインターを返すことで逃げることができます。ただし、別の関数呼び出しがスタック内のメモリを再利用した後にそのポインタが再利用された場合、プログラムの動作は未定義になるため、これは悪い習慣です。

int *fun()
{
    int point;
    point = 12;
    return (&point);
}

またはほぼ同じ:

int *fun()
{
    int point;
    int *point_ptr;
    point_ptr = &point;
    *point_ptr = 12;
    return (point_ptr);
}

別の悪い習慣ですが、より安全な方法は、整数値を静的変数として宣言することです。そうすると、スタックに置かれず、別の関数で使用されることから安全になります。

int *fun()
{
    static int point;
    int *point_ptr;
    point_ptr = &point;
    *point_ptr = 12;
    return (point_ptr);
}

または

int *fun()
{
    static int point;
    point = 12;
    return (&point);
}

他の人が述べたように、これを行う「正しい」方法は、mallocを介してヒープにメモリを割り当てることです。

19
invaliddata

整数ポインターへの値12の割り当て時にメモリーを割り当てていません。したがって、メモリが見つからないため、クラッシュします。

これを試すことができます:

#include<stdio.h>
#include<stdlib.h>
int *fun();

int main()
{
    int *ptr;
    ptr=fun();
    printf("\n\t\t%d\n",*ptr);
}

int *fun()
{
    int ptr;
    ptr=12;
    return(&ptr);
}
0
Varun Chhangani