Странная проблема с указателем - PullRequest
3 голосов
/ 13 октября 2010

Сегмент кода, приведенный ниже, компилируется и при запуске дает результат в виде:

$ make
gcc -g -Wall -o test test.c
$ ./test
string

/ * code1 * /

#include<stdio.h>
char *somefunc1()
{
   char *temp="string";
   return temp;
}
int main(int argc,char *argv[])
{
   puts(somefunc1());
   return 0;
}

тогда как небольшая модификация этого кода дает другие результаты:

$ make
gcc -g -Wall -o test test.c
test.c: In function ‘somefunc1’:
test.c:5: warning: function returns address of local variable
$ ./test

/* code 2 */

#include<stdio.h>
char *somefunc1()
{
   char temp[] ="string";
   return temp;
}
int main(int argc,char *argv[])
{
   puts(somefunc1());
   return 0;
}

Почему это происходит?

Ответы [ 4 ]

4 голосов
/ 13 октября 2010

В первом примере вы возвращаете адрес строкового литерала.Этот литерал существует до тех пор, пока программа выполняется, так что код безопасен.

Во втором примере вы создаете (локальный) функциональный массив, который инициализируется, чтобы содержать строку string.Затем вы продолжаете возвращать адрес (первый элемент) этого массива, но массив уничтожается, как только вы покидаете функцию.Об этом предупреждает ваш компилятор.Использование указателя, возвращенного из somefunc1, приводит к неопределенному поведению , поскольку он больше не ссылается на существующий объект.

4 голосов
/ 13 октября 2010

char *temp = "string"; создаст указатель temp, который указывает на строку строки.Этот строковый литерал хранится в сегменте данных исполняемого кода.Он неизменен, и адрес остается действительным после возврата из функции.

char temp[] = "string"; выделит 7 символов в стеке и установит их равными 'string'Это изменчивые персонажи.В вашем примере возвращаемое значение указывает на символы, которые больше не действительны, когда их функция возвращает.

1 голос
/ 13 октября 2010

Переменные в стеке теряются после выхода из функции, поэтому во втором случае происходит «странное поведение».

0 голосов
/ 13 октября 2010

когда вы делаете char * temp = "string"; память для temp выделяется в куче и остается там до выполнения программы. тогда как, когда вы делаете char temp [] = "string"; память распределяется по стеку, который удаляется или становится недействительным, когда вы выходите из области видимости. Во второй программе в вашей программе, когда вы находитесь вне функции что-то1, возвращаемый указатель становится недействительным. В первом случае, поскольку массив находится в куче, память не становится недействительной. Но тогда у вас успешно слилась память.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...