当程序从该函数调谐器时,指向在函数中声明和定义的某些 C 字符串的指针不再有效.为什么?
the pointers to some c-strings, declared and defined in a function, are no longer valid when the program retunrs from that function. Why?
我想用一些配置数据初始化一个程序。它通过 argv[] 将它们作为 url 编码的 json 接收,对它们进行解码和反序列化,并将它们交给类内的方法,该方法应该将相关变量设置为提交的值。
变量的类型为 c-string,因此我先进行转换,然后再将值分配给在方法外部声明的变量。 如果从指针中读出那些新设置的值,只要我留在此方法中,一切都很好。离开它后,从手动配置数据设置值的变量仅包含垃圾,而从字符串文字填充的变量完全没问题。
我打印了有关变量类型(typeid().name()的信息。虽然它们不一定是人类可读的,但比较显示,它们都是它们应该的类型。接下来比较方法内外指针的值 - 它们是相同的。
/* Config.cpp */
using json = nlohmann::json;
const char *Config::DB_HOST;
const char *Config::DB_USER;
const char *Config::DB_PASSWORD;
const char *Config::DB_NAME;
const char *Config::DB_SOCK;
Config::Config() {}
void Config::initDB(json dbConfig) {
string host = dbConfig["host"];
DB_HOST = host.c_str();
string user = dbConfig["user"];
DB_USER = user.c_str();
string pass = dbConfig["pass"];
DB_PASSWORD = pass.c_str();
string name = dbConfig["name"];
DB_NAME = name.c_str();
DB_SOCK = "/var/run/mysqld/mysqld.sock";
}
我对变量设置的值与字符串文字设置的值之间的差异感到特别困惑。前者失败,后者有效。它们之间有什么区别?在论坛上阅读了一些内容后,我了解到c_str()应该返回与文字完全相同的数据类型(指向数据的以null结尾的指针)。
感谢您的提示!
当你这样做string host = dbConfig["host"];
你创建一个函数本地std::string
,其中包含dbConfig["host"]
返回的内容的副本。 然后,使用c_str()
获取指向该本地字符串数据的指针。 在函数结束时,本地字符串被销毁,所以现在你有一个指向垃圾的指针。
另一方面,DB_SOCK = "/var/run/mysqld/mysqld.sock";
是不同的。"/var/run/mysqld/mysqld.sock"
是一个字符串文字,它具有静态存储持续时间,这意味着它将一直存在到程序结束。 这就是为什么该字段在函数结束后仍然有效的原因。
规则是,除非static
函数本地对象,否则不能引用或指向函数本地对象的指针。 如果没有,它会被销毁,留下一个悬空的指针/引用。
如果dbConfig["host"]
返回对std::string
的稳定引用,则可以使用DB_HOST = dbConfig["host"].c_str();
。 如果没有,那么我建议将变量更改为std::string
的,以便它们正确复制。
使用以下命令将局部变量存储在成员内部:
string host = dbConfig["host"];
DB_HOST = host.c_str();
所以一旦host
超出范围,你就会有悬空的指针。
文字 C 字符串具有静态持续时间,因此您可以将其存储在全局中,而不会出现生存期问题。
您可以将成员从const char*
更改为std::string
以避免该问题:
std::string Config::DB_HOST;
- 不同翻译单元中不可重载的非内联函数定义
- Visual Studio中的函数声明和函数定义问题
- 编写代码时C++出现错误:错误 1 错误 C2601:'circle':本地函数定义是非法的
- 具有enable_if外部类原型的模板类构造函数定义
- 类的前向声明之后的类成员函数定义,在类声明之前
- 为函数定义符号不明确的指针参数
- C++模板专用化 - 无法匹配函数定义
- 错误:在第 6 行'{'标记之前,此处不允许使用函数定义
- 找不到 #define 的函数定义
- 根据类型特征更改函数定义?
- 将抽象基类中的所有纯虚函数定义为 varaidaic 模板
- 命名空间更改函数定义
- "Type&"与C++函数定义中的"Type*"
- C++:为什么允许在另一个函数中声明函数,而不允许在函数定义中声明?
- 如何从 C++ 中的现有模板函数定义新函数
- 私有在函数定义/实现的返回值范围内是什么意思 (c++)?
- 越界成员函数定义是否需要一个完全限定的类名,直到全局范围
- 为什么c++允许成员函数定义中实例的私有成员访问
- Qt基类函数定义
- C++函数定义中参数列表后面额外一对括号的含义