我有一个模板函数,该函数将接收一个枚举器,并将其转换为C样式的以null终止的字符串。我了解该程序存在逻辑错误,因为函数的局部变量通过引用作为返回值传回。但是,该程序的执行没有错误或警告(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";
}
}
}
答案 0 :(得分:4)
程序正确。字符串文字具有整个程序的生命周期,因此可以保证始终可用。
但是,该程序是不必要的冗长。
return str = "ERROR: unmatched grade";
与
相同return "ERROR: unmatched grade";
但是更干净。
答案 1 :(得分:1)
这是安全的,因为字符串文字具有静态存储持续时间-意味着它们在程序的生存期内一直存在。
您可以简单地返回字符串文字
return "D+";
即使您确实将其分配给了局部变量并返回了该变量(此处也有更明确的显示:)
str = "D+";
return str;
这是安全的,在函数返回指向它的指针之后,字符串文字存在。 (虽然str
变量超出范围,但是您正在返回该str
指针的副本,该指针指向在应用程序整个生命周期中存在的字符串文字的开头。) / p>