C - вернуть указатель на символ без malloc - PullRequest
7 голосов
/ 15 декабря 2011

Рассмотрим следующий код:

char* pointerTesting(void) {

    char* test = "hello";
    return test;
}

int main() {

   char* string = pointerTesting();
   printf("string: %s\n", string);
}

Нет проблем с компиляцией и запуском. Однако, насколько я понимаю, это не должно работать, так как память, выделенная для указателя test, находится в стеке и уничтожается при возврате в main.

Итак, вопрос в том, как это работает без malloc в функции pointerTesting ()?

Ответы [ 3 ]

14 голосов
/ 15 декабря 2011

В этом случае строка "hello" сохраняется в глобальной памяти *. Так что уже выделено.

Следовательно, он по-прежнему действителен, когда вы возвращаетесь из функции.

Однако, если вы сделали это:

char test[] = "hello";
return test;

Тогда нет, это не сработало бы. (неопределенное поведение) В этом случае строка на самом деле является локальным массивом, который больше не работает, когда функция возвращает.

* Хотя обычно это так, в стандарте не говорится, что он должен храниться в глобальной памяти.
Но важной частью является то, что время жизни строкового литерала - это длительность Вся программа. (см. комментарии)

5 голосов
/ 15 декабря 2011

Вы возвращаете значение из test, которое является адресом первого символа строкового литерала "hello" (который, как и все строковые литералы, хранится в виде массива char таким образом, чтобы он был доступен на протяжении всей жизни программы).Если вы пытаетесь вернуть адрес из test для дальнейшего использования, то да, у вас возникнут проблемы.

Теперь следующий фрагмент не будет работать:

char *pointerTesting(void)
{
  char test[] = "hello";
  return test;
}

В этом случае вы пытаетесь вернуть адрес первого элемента в объекте массива, которыйявляется локальным для функции, которая будет недействительной после выхода из функции.Помните, что в большинстве случаев выражение типа «массив N-элементов из T» будет заменено выражением типа «указатель на T», значением которого является адрес первого элемента в массиве.

2 голосов
/ 15 декабря 2011

Хитрость в том, что память, на которую ссылается test, не находится в стеке, как вы ожидаете. См. Строковые литералы: куда они идут? для некоторых объяснений.

...