Возвращение локального строкового литерала символом * - PullRequest
0 голосов
/ 09 октября 2018

У меня есть шаблонная функция, которая получит перечислитель и преобразует его в строку с нулем в конце в стиле Си.Я понимаю, что в этой программе есть логическая ошибка, так как локальная переменная функции возвращается как возвращаемое значение по ссылке.Однако программа выполняется без ошибок или предупреждений (Visual Studio 17).Это приведет к неопределенному поведению или утечке памяти?Когда str выходит из области видимости, возвращается ли копия адреса, а переменная-указатель уничтожается?Это хорошая практика программирования?

Другой вариант, который я могу придумать, - это создание динамической памяти.Например, const char* str = new char[size].

#include <iostream>
#include <string>

namespace Letter {
    enum class Letter {
        AP, // A+
        A,  // A
        BP, // B+
        B,  // B
        CP, // C+
        C,  // c
        DP, // D+
        D,  // D
        F   // F

    };

    template <typename T>
    const char* convertToStr(const T& t) {
        const char* str;

        switch (t) {
        case Letter::AP:
            return str = "A+";
        case Letter::A:
            return str = "A";
        case Letter::BP:
            return str = "B+";
        case Letter::B:
            return str = "B";
        case Letter::CP:
            return str = "C+";
        case Letter::C:
            return str = "C";
        case Letter::DP:
            return str = "D+";
        case Letter::D:
            return str = "D";
        case Letter::F:
            return str = "F";
        default:
            return str = "ERROR: unmatched grade";
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

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

Вы можете просто вернуть строковый литерал

 return "D+"; 

Даже если вы присвоили его локальной переменной и вернули это (показано здесь более явно:)

str = "D+";
return str;

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

0 голосов
/ 09 октября 2018

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

Однако программа является ненужной, многословной.

return str = "ERROR: unmatched grade";

- это то же самое, что и

return "ERROR: unmatched grade";

, но чище.

...