Короткий ответ - то, что Ориентированный на выражение языки программирования позволяют больше сжатого кода. Они не вынуждают Вас к отдельные команды от запросов .
Если у вас есть функция, которая возвращает " строковые литералы ", тогда он должен вернуть const char *. Их не нужно выделять в куче с помощью malloc, потому что они компилируются в раздел только для чтения самого исполняемого файла.
Пример:
const char* errstr(int err)
{
switch(err) {
case 1: return "error 1";
case 2: return "error 2";
case 3: return "error 3";
case 255: return "error 255 to make this sparse so people don't ask me why I didn't use an array of const char*";
default: return "unknown error";
}
}
Подумал, что я хотел бы резюмировать и прокомментировать некоторые из приведенных выше комментариев:
Итак, в C у вас будет
const char *my_function() {
const char *my_str = (const char *)malloc(MY_STR_LEN + 1); // +1 for null terminator.
/* ... */
return my_str;
}
int main() {
const char *my_str = my_function();
/* ... */
free(my_str);
/* ... */
return 0;
}
Обычно это не проблема, но есть вещи, которые следует учитывать. Обычно это вопрос константной корректности, что означает отслеживание того, что вы можете изменить, а что нет.
Если вы возвращаете строку в двойных кавычках, это const char *
, и относиться к нему как к чему-либо другому - это приглашение к неприятностям. Изменение такой строки является неопределенным поведением, но обычно приводит к сбою программы или изменению этой строки везде, где она упоминается.
Если вы вернете массив символов в стеке (т. Е. Локальную переменную вызываемой функции), он будет прочь, и указатель не будет указывать ни на что конкретное, возможно, в какой-то момент с плохими результатами.
Если вызываемая функция возвращает что-то, что уже const char *
, затем изменение его на char *
требует приведения. Кроме того, если вы действительно собираетесь его изменить, вы должны быть уверены, что он изменяемый. Обычно гораздо лучше оставить его как const char *
.
Нет немедленных проблем с возвратом памяти, выделенной с помощью malloc ()
или new
, но вы есть проблема владения: какая функция должна free ()
/ удалить
его, когда и что делать с возможными копиями? Вот где сияют умные указатели C ++.
malloc ()
или new
, но у вас есть проблема владения: какая функция должна free ()
/ удалить
это, когда и что делать с возможными копиями? Вот где сияют умные указатели C ++. s нет непосредственной проблемы с возвратом памяти, выделенной с помощью malloc ()
или new
, но у вас действительно есть проблема владения: какая функция должна free ()
/ удалить
это, когда и что делать с возможными копиями? Вот где сияют умные указатели C ++. Простое изменение кода возврата не вызовет сбоя. Однако если возвращаемая вами строка является статической (например, return «AString»
), вы должны вернуть const char *
, чтобы убедиться, что компилятор обнаруживает любую попытку модификации этой памяти, которая скорее всего вызовет сбой. Конечно, вы можете использовать приведение типов и тому подобное, чтобы обойти проверки компилятора, но в этом случае вам придется работать , чтобы произошел сбой.
Если символ * выделен в стеке, вы возвращаете висячий указатель. В противном случае, если он соответствует прототипу функции, а объявление соответствует возвращаемому значению, все будет в порядке.