Возвращение строк в функции C, требуется пояснение - PullRequest
2 голосов
/ 18 августа 2010

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

int x = 1;
return x;

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

Ответы [ 4 ]

8 голосов
/ 18 августа 2010

Причина проста, но тонка: Функции C не могут быть объявлены для возврата массивов.

Когда вы возвращаете указатель, вот так:

char *foo(void)
{
    char x[] = "hello";
    return x;
}

return x; - это , а не , фактически возвращающий x. Он возвращает указатель на первый элемент x 1 - это то же самое, что сказать:

return &x[0];

Должно быть более понятно, почему это не правильно - это точно аналогично этому:

int *foo(void)
{
    int x = 100;
    return &x;
}

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

struct xyzzy {
    char x[10];
};

struct xyzzy foo(void)
{
    struct xyzzy x = { "hello" };
    return x;
}


1. Это является следствием правила особого случая для типов массивов. В выражении, если массив не является субъектом унарных операторов & или sizeof, он вычисляет указатель на свой первый элемент. Попытка определить настоящий массив в C - это все равно, что попытаться поймать туман в ваших руках - он просто исчезает, заменяется указателем.
3 голосов
/ 18 августа 2010

Целое число является примитивным типом, поэтому его значение возвращается как таковое. Однако в Си строка не является примитивным типом, поэтому вы объявляете ее как массив символов. И когда вы возвращаете массив, вы фактически возвращаете указатель на исходный массив, так что это своего рода возврат по ссылке, если хотите. Но, как вы можете видеть, указатель на char x[] недействителен после выхода из функции.

2 голосов
/ 18 августа 2010

Пожалуйста, посмотрите подробный ответ, который я написал о этом .Не только то, что в C переменные, созданные в области функций, используют автоматическую кучу стека, в которой будут храниться переменные, а когда функция возвращает, эта куча уничтожается, именно здесь используются локальные переменные, особенно типастрока, т.е. char [] или указатель на строку должны быть размещены в куче вне области действия функции, в противном случае будет возвращен мусор.Обходной путь для этого должен использовать статический буфер или использовать malloc.

1 голос
/ 18 августа 2010

Этот массив символов размещается в области действия функции (а не динамически, например, с помощью malloc ()), поэтому он будет недоступен за пределами этой области.

Два способа обойти это:

  1. Объявите, что массив символов будет static
  2. Выделите буфер в вызывающей функции, передав его в качестве аргумента, тогда эта функция просто заполняет его.
...