【发布时间】:2016-03-11 19:15:11
【问题描述】:
我正在处理一个头文件,该文件定义了一个命名空间,其中定义了一些 c 字符串。
namespace env {
const char* C_NAME;
const char* SYS_DRIVE;
const char* PROCESSOR;
const char* PROCESSOR_ARCHITECTURE;
const char* OSNAME;
}
我的主要功能是这样的:
int main(int argc, char* argv[], char* env[]) {
initialize_environment_vars(env);
cout << "C_NAME\t\t\t" << env::C_NAME << endl;
/*...*/
return 0;
}
我的问题是我在initialize_environment_vars() 中初始化的字符串没有我想要的值。
void initialize_environment_vars(char* env[]) {
int id = PRIVATE::findEntry(env, "COMPUTERNAME");
env::C_NAME = (str::getAfter(env[id], "=")).c_str(); // getAfter() returns a string
//std::cout << env::C_NAME << std::endl; //Right value!!!
id = PRIVATE::findEntry(env, "SystemDrive");
std::cout << env::C_NAME; //Value at env[id]
/*Here the other constants are initialized in the same way.*/
}
我发现在函数 initialize_environment_vars() 中变量的值是正确的,直到我调用函数 findEntry() 来查找另一个条目。
int PRIVATE::findEntry(const char* const arr[], std::string toFind) {
bool found = false;
int i = 0;
std::string actual;
while(arr[i] && !found) {
actual = arr[i];
if(str::contains(actual, toFind)) {
found = true;
break;
}
i++;
}
if(found)
return i;
else { /*Error message and exit program*/ }
}
看了string::c_str query这个帖子,我也觉得我在initialize_environment_vars()中使用.c_str()是错误的,因为调用.c_str()后返回的字符串会被销毁,但是这好像不是确实如此,因为env::C_NAME 在main() 中有效。
因此我有两个问题:
- 为什么我的
PRIVATE::findEntry(const char* const [], std::string)函数会像我上面使用的那样更改env::C_NAME的值,即使它只返回一个int并且没有修改数组或条目? - 为什么
env::C_NAME在'main()' 中仍然有效?str::getAfter(const std::string&, std::string)返回的字符串的析构函数被调用后不应该失效吗? (已回答)
【问题讨论】:
-
"我还认为我在initialize_environment_vars()中使用.c_str()是错误的,因为调用.c_str()后返回的字符串会被销毁 “ 答对了! “但这似乎不是这样,因为 env::C_NAME 在 main() 中是有效的。” 嗯?
-
@David Schwartz 我刚刚重新阅读了另一篇文章的答案并理解了我第二个问题的答案。嗯?:我的意思是,在
main()我得到了我期望的行为,所以我认为它总是可以正常工作。但现在我知道这是错误的。 -
没有理由你应该期待任何特定的行为,因为你知道你正在访问无效的东西。你怎么知道会发生什么? (没有深入的编译器/平台知识。)
-
您无法通过查看或使用值来确定值是否有效。一旦一个物体被摧毁,它的残骸就会留在原来存放的地方。 (同样,你不能通过检查某人的尸体是否还在那里来确定他是否还活着。)
-
@molbdnilo 我现在正在使用这个类比...太棒了!