Висячий указатель в случае целочисленного указателя против указателей на символы - PullRequest
0 голосов
/ 12 мая 2018

Я пытаюсь понять, как работают висячие указатели в c ++.

int* get_int_ptr()
{
    int i=10;
    int* ptr;
    ptr = &i;
    return ptr;
}

char* get_char_ptr()
{
    char str[10];
    strcpy(str,"Hello!");
    return(str); 
}

int main()
{
    cout << *get_int_ptr() << endl;
    cout << get_char_ptr() << endl;
    return 0;
}

Вывод этого кода -

Предупреждения:

prog.cpp: In function 'char* get_char_ptr()':
prog.cpp:16:9: warning: address of local variable 'str' returned [-Wreturn-local-addr]
char str[10];
    ^

Вывод:

10

Может кто-нибудь объяснить, почему значение i печатается в функции main(), даже если возвращаемый указатель указывает на i, который вышел из области видимости.

И почему значение str не печатается.

Is int* и char* обрабатываются отдельно с точки зрения области действия функции.

Кроме того, делает лииспользование smart_pointers здесь поможет в любой форме?

Ответы [ 2 ]

0 голосов
/ 12 мая 2018

Как вы знаете, возврат указателя на локальную переменную не гарантируется.Поэтому нельзя ожидать, что ни ваша get_int_ptr, ни ваша get_char_ptr функция будут работать.

(Предвещая ответ: «не гарантировано, что работает» не совсем то же самое, что «гарантированно не будет работать».)

Вы экспериментировали с функцией get_int_ptr.К вашему удивлению вызывающая программа «правильно» напечатала 10.

Вот аналогия.То, что вы сделали, похоже на эту маленькую историю:

Я работал над своей машиной.Я снял переднее колесо, чтобы починить тормоза.Когда я снова поставил переднее колесо, я забыл установить гайки с проушинами, поэтому колесо на самом деле не было прикреплено.Затем я поехал в магазин, чтобы купить немного молока.Но колесо не отвалилось.Почему бы и нет?

И ответ таков: вам очень, очень повезло.

Затем вы экспериментировали с вашей функцией get_char_ptr.И это не удалось.Это не удивительно, если только вы не представите, что успех эксперимента get_int_ptr каким-то образом доказал, что в конце концов можно использовать висячие указатели.Продолжая аналогию:

На следующий день с отсутствующими гайками ушки я поехал по пересеченной местности, чтобы навестить свою стареющую бабушку.На полпути, проезжая со скоростью 60 миль в час по шоссе, переднее колесо внезапно оторвалось, и я врезался в кювет, снося мою машину.Почему это произошло?

Нет нужды говорить, что это произошло из-за отсутствия зажимных гаек!Ничто не удерживало переднее колесо, и ваш очевидный «успех» в предыдущий день, когда он ехал в магазин в таком сломанном состоянии, ничего не доказал.

Я согласен, что интригует, что одна из ваших функций «сработала»другой нет.Но это было в основном случайное происшествие.Нет, между указателями int* и char* нет никакой разницы в этом отношении: они оба с одинаковой вероятностью не сработают при зависании.

Иногда можно объяснить, почему случайное происшествие происходит так, как оно происходит,Здесь, однако, я не могу.Я попробовал вашу программу под моим компилятором, и я вижу точно такой же результат.Локальная переменная get_int_ptr i имеет тенденцию выживать, но локальный массив get_char_ptr str имеет тенденцию очищаться.Я ожидаю, что биты str могут выжить, но, очевидно, нет.Но, опять же, не имеет значения, что мы не можем объяснить поведение, потому что оно undefined .

0 голосов
/ 12 мая 2018

Это случайно, что что-то напечатано.

Оба указателя указывают на локальную переменную, которая перестает существовать, когда функция возвращается.

Это классический пример неопределенного поведения.

Может случиться что угодно - программа может заказать пиццу, взорвать или напечатать что-нибудь, иногда даже правильное значение.

...