Функция, возвращающая адрес локальной переменной ошибки в C

У меня есть следующий код:

char* gen() { char out[256]; sprintf(out, ...); // you don't need to know what's in here I don't think return out; } 

И я получаю эту ошибку, когда пытаюсь скомпилировать:

 ERROR: function returns address of local variable 

Я пробовал использовать этот возврат char[] и char без везения. Я что-то упускаю?

Ваша переменная array массива существует только внутри тела функции.
Когда вы вернетесь из функции, содержимое out буфера больше не доступно, оно просто локально для этой функции.

Если вы хотите вернуть некоторую строку из вашей функции вызывающему, вы можете динамически распределить эту строку внутри функции (например, с помощью malloc() ) и вернуть указателю на эту строку вызывающему, например

 char* gen(void) { char out[256]; sprintf(out, ...); /* * This does NOT work, since "out" is local to the function. * * return out; */ /* Dynamically allocate the string */ char* result = malloc(strlen(out) + 1) /* +1 for terminating NUL */ /* Deep-copy the string from temporary buffer to return value buffer */ strcpy(result, out); /* Return the pointer to the dynamically allocated buffer */ return result; /* NOTE: The caller must FREE this memory using free(). */ } 

Другим более простым вариантом было бы передать указатель out buffer в качестве параметра char* вместе с размером буфера (чтобы избежать переполнения буфера).

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

 /* Pass destination buffer pointer and buffer size */ void gen(char* out, size_t out_size) { /* Directly write into caller supplied buffer. * Note: Use a "safe" function like snprintf(), to avoid buffer overruns. */ snprintf(out, out_size, ...); ... } 

Обратите внимание, что вы явно указали «C» в заголовке вопроса, но вы добавили тег [c++] . Если вы можете использовать C ++, проще всего использовать строковый class, такой как std::string (и позволить ему управлять всем распределением / очисткой памяти буфера).

Когда вы используете следующее объявление в функции char out[256]; выделенное пространство будет освобождено после возвращения функции, поэтому нет смысла возвращать указатель на массив out char .

Если вы хотите вернуть указатель на строку, которую вы создаете в функции, вы должны использовать malloc() как в

 char* out = (char*)malloc(256*sizeof(char)); 

который выделяет пространство для 256 char но должен быть освобожден вручную в какой-то момент функцией free() .

Или, как было предложено в комментарии Брайана Би, передать char * который указывает на строку, которую вы хотите использовать в качестве аргумента для вашей функции.

Проблема в том, что когда функция gen возвращает (выходит), ее локальные переменные (например, out ) заканчиваются из области действия и больше недоступны для вызывающего. Итак, когда вы возвращаетесь out вы возвращаете указатель на память, которая больше не выделяется.

Существует два варианта «вернуть» указатель / буфер из функции:

  1. Выделите буфер в вызывающей функции и передайте его в gen :

     char out[256]; gen(out, sizeof out); 

    обычно также предоставляется размер буфера, в который вы проходите, поскольку вызываемая функция не может этого знать. Это означает, что вы должны изменить объявление gen на:

     void gen(char * out, size_t size){ 

    Вы также можете жестко закодировать размер входящего буфера до 256 (поскольку у вас есть жестко закодированное в вашей функции gen прямо сейчас):

     void gen(char out[256]){ 

    Это означает, что вы должны предоставить переменную типа char[256] в gen (и никакие другие указатели или массивы). Но это позволяет вам делать sizeof out внутри gen .

  2. Выделяйте буфер динамически внутри функции:

     char * out = malloc(256 * sizeof *out); // ... return out; 

    это имеет преимущество, что декларация gen не изменяется. Но это означает, что вызывающая функция должна free возвращенный буфер, когда он будет с ним выполнен.

  • Декодирование и проверка токена JWT с использованием System.IdentityModel.Tokens.Jwt
  • Как получить список каталогов в C?
  • Почему мы не можем использовать двойной указатель для представления двухмерных массивов?
  • Несколько символов в символьной константе
  • плавать до неожиданного поведения
  • локальная переменная, инициализированная нулем в C
  • Как работает getchar ()?
  • Как проверить, соответствует ли значение строке
  • Отключение политики одного и того же происхождения в Safari
  • C - передача массива 2d в качестве аргумента функции?
  • В чем смысл этой части кода? void (* signal (int sig, void (* func) (int))) (int);
  • Давайте будем гением компьютера.