Страница 1 из 2

указатель на локальную переменную

Добавлено: 26 сен 2004, 13:11
versus
привет
подскажи плз, что то я запутался

вот на такой код, gcc, естественного говорит ворнинг про использоване адреса локальной переменной

Код: Выделить всё

#include <stdio.h>
#include <unistd.h>

char* some_function()
{
    char str[1024] = "hello world!";

    return str;
}

int main()
{
    char* ptr;
    ptr = some_function();

// usleep((long)1E3) /* подождать пока локальная переменная удалится 

    printf("%s\n", ptr);

    return 0;
}
понятно, что код этот совсем некорректен, в том смысле что лучше было бы использовать malloc и free, но все таки не смотря на ворнинг к большому для меня удивлению программа все таки печатает "hello world!".. как это понимать? разве память занимаемая str не должна удалится после завершения some_function? и тогда при попытке printf получится segfault... однако вместо этого нормальный вывод. Почему?

Добавлено: 26 сен 2004, 13:37
Absurd
Этот код работает случайно, потому что компилятору нет резона занулять локальные переменные, и они там остаются по старым адресам.
Но программист должен думать, что там уже ничего нет.

Добавлено: 26 сен 2004, 13:42
Hup
Я так полагаю. что строка просто висит в памяти... Нужно посмотреть Турбо дебагером дамб памяти

Добавлено: 26 сен 2004, 14:09
versus
Absurd, спасибо.

Добавлено: 27 сен 2004, 18:14
Kolinus
Absurd прав. Как говорят мои преподаватели - это типичная ошибка второкурсника.
Если после вызова some_function обЪявить еще какую-нить переменную и проинициализировать ее то ptr скорее всего "свалится" с нужной тебе строки

Добавлено: 28 сен 2004, 11:19
Absurd
В принципе, если есть большая нужда возвращать строчку типа const char * или char * (хуже), то можно массив str[] объявить как
статический

Код: Выделить всё

const char* some_function()
{
    static char str[1024] = "hello world!";
    return str;
}
В таком случае строка str будет жить не в стеке, а в области данных, где ее никто не будет трогать.

Добавлено: 28 сен 2004, 16:40
Kolinus
Еще есть способ - после того как сделал вызов такого метода, сразу вызывать strcpy в локальную переменную функции main - но это опять же если только сильно надо ;)

Добавлено: 29 сен 2004, 17:43
Hawk
Удивительно но факт, следующий код так же будет полностью корректным -

Код: Выделить всё

const char* some_function() 
{ 
    char* str = "hello world!"; 
    return str; 
} 
в этом случае строчка "hello world!" становится статической константой и существует даже до вызова функции не говоря уж о возвращении из неё. В отличии от char str[1024] = "hello world!" когда создается локальный массив с который копируется эта статическая строчка

Добавлено: 29 сен 2004, 18:24
Eugie
Hawk, неудивительно: по-сути ты просто возвращаешь адрес на константную строку (литерал), неважно, что объявленный локально - он все равно фиксирован в памяти

Добавлено: 29 сен 2004, 18:35
Hawk
Eugie и я о том же