Могут/Почему с помощью символа * вместо символа константы *, в ответ вводят катастрофические отказы причины?

Короткий ответ - то, что Ориентированный на выражение языки программирования позволяют больше сжатого кода. Они не вынуждают Вас к отдельные команды от запросов .

6
задан Andy 14 September 2009 в 13:51
поделиться

5 ответов

Если у вас есть функция, которая возвращает " строковые литералы ", тогда он должен вернуть 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";
    }
}
14
ответ дан 8 December 2019 в 02:53
поделиться

Подумал, что я хотел бы резюмировать и прокомментировать некоторые из приведенных выше комментариев:

  1. Да, TDD касается дизайна. Речь идет не о тестировании.
  2. Не уверен, почему QA участвовал в стадии проектирования Джорджа. Похоже, они указали автоматические тесты. Как заметил Тим, это процесс разработки.
  3. Кевин, вы сказали «пропустите тестирование». Еще раз. TDD - это дизайн, а НЕ тестирование. ОК. Вы можете пропустить разработку, но готовое приложение будет содержать ошибки и не поддерживать.
  4. Рошан упомянул «исполняемая спецификация того, что должен делать ваш компонент». Это означает полностью актуальную документацию. Когда вы новичок в проекте, вы можете быстро освоить его, вы можете точно увидеть, что задумал исходный разработчик. И, как сказал Джон, вы можете вносить изменения в код и следить за тем, чтобы ничего не сломалось. s был возвращен вам после того, как вы закончите с ним, или вы потеряете память. Разве C / C ++ не такие замечательные языки?

    Итак, в 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;
    }
    
11
ответ дан 8 December 2019 в 02:53
поделиться

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

Если вы возвращаете строку в двойных кавычках, это const char * , и относиться к нему как к чему-либо другому - это приглашение к неприятностям. Изменение такой строки является неопределенным поведением, но обычно приводит к сбою программы или изменению этой строки везде, где она упоминается.

Если вы вернете массив символов в стеке (т. Е. Локальную переменную вызываемой функции), он будет прочь, и указатель не будет указывать ни на что конкретное, возможно, в какой-то момент с плохими результатами.

Если вызываемая функция возвращает что-то, что уже const char * , затем изменение его на char * требует приведения. Кроме того, если вы действительно собираетесь его изменить, вы должны быть уверены, что он изменяемый. Обычно гораздо лучше оставить его как const char * .

Нет немедленных проблем с возвратом памяти, выделенной с помощью malloc () или new , но вы есть проблема владения: какая функция должна free () / удалить его, когда и что делать с возможными копиями? Вот где сияют умные указатели C ++.

s нет непосредственной проблемы с возвратом памяти, выделенной с помощью malloc () или new , но у вас есть проблема владения: какая функция должна free () / удалить это, когда и что делать с возможными копиями? Вот где сияют умные указатели C ++.

s нет непосредственной проблемы с возвратом памяти, выделенной с помощью malloc () или new , но у вас действительно есть проблема владения: какая функция должна free () / удалить это, когда и что делать с возможными копиями? Вот где сияют умные указатели C ++.

4
ответ дан 8 December 2019 в 02:53
поделиться

Простое изменение кода возврата не вызовет сбоя. Однако если возвращаемая вами строка является статической (например, return «AString» ), вы должны вернуть const char * , чтобы убедиться, что компилятор обнаруживает любую попытку модификации этой памяти, которая скорее всего вызовет сбой. Конечно, вы можете использовать приведение типов и тому подобное, чтобы обойти проверки компилятора, но в этом случае вам придется работать , чтобы произошел сбой.

1
ответ дан 8 December 2019 в 02:53
поделиться

Если символ * выделен в стеке, вы возвращаете висячий указатель. В противном случае, если он соответствует прототипу функции, а объявление соответствует возвращаемому значению, все будет в порядке.

2
ответ дан 8 December 2019 в 02:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: