【问题标题】:C++ extern const char* not working as expectedC++ extern const char* 没有按预期工作
【发布时间】:2017-03-14 11:45:03
【问题描述】:

我以前使用过 extern 关键字,但现在我遇到了一个非常奇怪的问题。

首先我有一个包含外部变量声明的 common.hh 文件:

//some extern declarations
extern const char* PATH;

在我的 main.cc 中,我执行以下操作(暂时忽略 cout):

#include "common.hh"
const char* PATH;

int main(const int argc, const char* argv[]){
PATH = somePath.c_str();
//std::cout << PATH << std::endl; //will print the correct path
//std::cout << std::string(PATH) << std::endl; //will fix the problem occuring later
//some function calls to other files where PATH is used
//... somePath still in scope ...
//... somePath is about to be destroyed
}

现在我有其他文件 Other.hh 和 Other.cc 出现问题: 首先是我的Other.hh

#include "common.hh"
//function declarations and some other stuff

在Other.cc中出现访问PATH的问题:

#include "Other.hh"
void someFunction(...){
std::cout << PATH << std::endl; //When accessing PATH here again it prints garbage

在我的文件 Other.cc 中,我需要 main.cc 中定义的 const char* PATH,但由于某种原因 PATH 已更改。如果我在我的 main.cc 中的某处执行 std::string(PATH) ,整个问题就解决了,如上面的 cout 所示。我不明白出了什么问题,我所有的其他外部变量都可以正常工作。

编辑: 问题暂时解决了。我刚刚在 main.cc 中做了以下操作:

std::string tmp = somePath;
PATH = tmp.c_str();

我只是不明白为什么这可以解决问题,因为理论上 tmpsomePath 应该具有相同的范围,并且在 other.cc 中的函数调用执行之前不应该被销毁。换句话说:我在 other.cc 中的函数调用是在somePath 的范围结束之前。

【问题讨论】:

标签: c++ pointers char constants extern


【解决方案1】:

somePath.c_str() 的生命周期受somePath 变量的约束。一旦超出范围,PATH 就会指向将被重用的内存。

你能把PATH 变成std::string 而不是char* 吗?如果没有,您将不得不使用 strdup 或类似的东西来复制 somePath.c_str() 的值。

【讨论】:

  • 非常感谢。通过执行 string tmp = somePath; 解决了我的问题路径 = tmp.c_str();但我仍然不知道为什么,因为 tmp 和 somePath 应该具有相同的生命周期。在 somePath 超出范围之前,我使用 PATH,那么为什么即使 somePath.c_str() 仍在范围内,PATH 也会发生变化?
  • 在设置PATH 之后你不是在修改somePath 是吗? c_str 返回指向字符串缓冲区的原始指针。如果你修改了字符串,那么缓冲区也会被修改。
【解决方案2】:

c_strstd::string 的一种方法,如果字符串被更改或销毁,则该方法无效。例如,在之前的question 中查看有关c_str 生命周期的详细信息。

您可以将PATH 制作成std::string 并让它复制或手动复制到分配了足够内存的char *。然后考虑何时解除分配。


编辑 - 回复您的编辑

你在哪里

std::string tmp = somePath;
PATH = tmp.c_str();

您声称“tmp 和 somePath 应该具有相同的范围” - 他们没有。 PATH 在全局范围内,您已在此处指定它指向 tmpc_str()

【讨论】:

  • 非常感谢,我的问题已经解决了,虽然我不完全明白为什么。我编辑了我的问题以表明在 main.cc 中 other.hh/cc 中的一些函数调用在 somePath 应该仍在范围内并且因此不会被破坏的地方完成
  • 当您分配PATH 时会正常,但如果您稍后尝试读取它,在tmp 超出范围后,指针很可能会指向垃圾。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多