C++构造函数m_name未初始化报错及std::vector替代疑问
问题1:修复
Field 'm_name' is uninitialized when used here错误 你遇到的错误是因为strcpy的第一个参数需要指向一块已分配的内存空间,但你在初始化列表里直接用了还未初始化的m_name(此时是nullptr),属于非法内存访问。
解决方法有两种:
方法一:和默认构造函数一样使用
strdup,它会自动分配足够内存并拷贝字符串:explicit Student(const char *name) : m_name(strdup(name)), m_scores(0) {}注意:
strdup分配的内存需要用free释放,必须添加析构函数避免内存泄漏:~Student() { free(m_name); }另外,为避免浅拷贝问题,建议补充拷贝构造函数和赋值运算符重载(如果需要对象拷贝功能)。
方法二:手动分配内存后再拷贝:
explicit Student(const char *name) : m_scores(0) { if (name) { // 分配内存时要给终止符'\0'预留位置 m_name = new char[strlen(name) + 1]; strcpy(m_name, name); } else { m_name = new char[8]; // "No Name"长度为7,加终止符共8字节 strcpy(m_name, "No Name"); } }这种方式用
new[]分配的内存,需要用delete[]释放:~Student() { delete[] m_name; }
问题2:将
m_name改为std::vector<char>的错误解决 std::vector<char>是C++容器,不能直接和C风格字符串的strcpy/strdup混用,需用容器成员函数完成初始化:
首先修改成员变量:
private: std::vector<double> m_scores; std::vector<char> m_name;
然后修改构造函数:
explicit Student(const char *name) : m_scores(0) { if (name) { size_t str_len = strlen(name); // 分配足够空间,包含终止符'\0' m_name.resize(str_len + 1); // 拷贝字符串内容到vector std::copy(name, name + str_len + 1, m_name.begin()); } else { const char* default_name = "No Name"; size_t str_len = strlen(default_name); m_name.resize(str_len + 1); std::copy(default_name, default_name + str_len + 1, m_name.begin()); } } Student() : m_scores(0) { const char* default_name = "No Name"; size_t str_len = strlen(default_name); m_name.resize(str_len + 1); std::copy(default_name, default_name + str_len + 1, m_name.begin()); }
不过更推荐直接用std::string代替vector<char>,它专门用于字符串处理,更安全简便:
修改成员变量为:
private: std::vector<double> m_scores; std::string m_name;
构造函数可简化为:
explicit Student(const char *name) : m_name(name ? name : "No Name"), m_scores(0) {} Student() : m_name("No Name"), m_scores(0) {}
这种方式无需手动管理内存,也能避免各类字符串操作错误。
内容的提问来源于stack exchange,提问作者0xDEADBEEF
相关产品推荐
相关产品推荐

