Возвращение указателя из функции - PullRequest
31 голосов
/ 13 октября 2011

Я пытаюсь вернуть указатель из функции. Но я получаю ошибку сегментации. Кто-нибудь подскажите пожалуйста что не так с кодом

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

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

Ответы [ 4 ]

46 голосов
/ 13 октября 2011

Выделите память перед использованием указателя.Если вы не выделяете память, *point = 12 - неопределенное поведение.

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

Также ваш printf неверенВам нужно разыменовать (*) указатель.

printf("%d", *ptr);
             ^
18 голосов
/ 15 октября 2011

Несмотря на то, что возвращение указателя на локальный объект является плохой практикой, здесь он не вызывает 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.

0 голосов
/ 28 июля 2014

Не выделяется память при присвоении значения 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 голосов
/ 30 мая 2014

Насколько мне известно, использование ключевого слова new делает относительно то же самое, что и malloc (sizeof identifier).Приведенный ниже код демонстрирует, как использовать ключевое слово new.

    void main(void){
        int* test;
        test = tester();
        printf("%d",*test);
        system("pause");
    return;
}
    int* tester(void){
        int *retMe;
        retMe = new int;//<----Here retMe is getting malloc for integer type
        *retMe = 12;<---- Initializes retMe... Note * dereferences retMe 
    return retMe;
}
...