我在将字符串值放入“字符串向量结构”时遇到问题。 最简单的可重现代码如下:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
struct ttt {
string name;
unsigned int ID;
vector<unsigned int> numList;
};
int main() {
vector<ttt> b;
b.reserve(3);
b[0].ID = 1;
b[0].numList.push_back(3);
b[0].numList.push_back(4);
string dd ("Desk");
b[0].name = dd;
cout << b[0].ID << b[0].name << b[0].numList[2] << endl;
return 0;
}
代码编译,但无法将“Desk”字符串放入b [0] .name,一个结构元素。分段故障在现场出现。
我也试过以下几行,但都失败了。
b[0].name.push_back(dd);
b[0].name += dd;
我的编译器是GCC g ++ 4.7.7 20120313, 我用下面的编译命令。
/usr/bin/g++ --std=gnu++0x -Werror -Wall -Wextra -Warray-bounds
真诚地感谢任何帮助。
答案 0 :(得分:2)
有两个错误:
直接分配b[0]
而不调用push_back
或不事先在构造函数调用中初始化它。
另一条违规行
b[0].numList[2]
因为您只调用了push_back()
两次,并且索引是从0开始的。
像这样直接初始化矢量会好得多:
#include <string>
#include <vector>
#include <iostream>
using namespace std;
struct ttt {
string name;
unsigned int ID;
vector<unsigned int> numList;
};
int main() {
vector<ttt> b{{"Desk", 1, { 3, 4 }}};
cout << b[0].ID << b[0].name << b[0].numList[1] << endl;
}
答案 1 :(得分:1)
您可能不会使用下标运算符为空向量分配新值。请改为使用push_back
成员函数。
例如
std::vector<ttt> b;
b.reserve( 3 );
//...
b.push_back( ttt() );
b.back().ID = 1;
//...
答案 2 :(得分:0)
Valgrind在该代码上报告的第一个错误是
==28307== Conditional jump or move depends on uninitialised value(s)
==28307== at 0x40154F: void std::vector<unsigned int, std::allocator<unsigned int> >::emplace_back<unsigned int>(unsigned int&&) (vector.tcc:94)
==28307== by 0x4012D7: std::vector<unsigned int, std::allocator<unsigned int> >::push_back(unsigned int&&) (stl_vector.h:933)
==28307== by 0x400F00: main (39273136.cpp:17)
虽然这看起来有点神秘,但有些经验表明要检查this
push_back()
的{{1}}参数是否已初始化。仔细查看代码,我们看到:
vector<ttt> b;
b.reserve(3);
b[0].ID = 1;
b[0].numList.push_back(3);
你已经告诉向量准备有3个元素,但是你永远不会向它添加任何ttt
个对象。当您访问b[0]
时,您正在使用未初始化的内存(Valgrind并未抱怨对b[0].ID
的分配,因为内存已分配并属于b
- 但调用{{1}尝试读取可能是随机垃圾的push_back
成员。
显而易见的解决方案是vector
(或以其他方式创建)emplace_back()
的元素。
答案 3 :(得分:0)
当您在向量上调用reserve()
时,它不会创建所包含类型的任何实例。 它只为元素分配空间。。因此,当您尝试访问向量中的这些位置时,您将获得未定义的行为。您必须首先将元素推入向量中,或者在尝试对其进行任何读取或写入之前,使用vector<ttt> b(6);
之类的调用对其进行零初始化。
仅编辑声明ttt
向量的一行并删除reserve()
调用修复此程序。
另外要注意,因为您尝试访问b[0].numList[2]
,第三个元素,但您只为两个元素执行了push_back
。
#include <vector>
#include <string>
#include <iostream>
using namespace std;
struct ttt {
string name;
unsigned int ID;
vector<unsigned int> numList;
};
int main() {
vector<ttt> b(3); //create 3 zero-init elements in vector b
b[0].ID = 1;
b[0].numList.push_back(3);
b[0].numList.push_back(4);
string dd ("Desk");
b[0].name = dd;
cout << b[0].ID << b[0].name << b[0].numList[2] << endl;
//^beware, this hasn't been initialized
return 0;
}
输出:1Desk0