我有一个问题,把字符串值放入"字符串的向量结构"。最简单的可复制代码如下:
#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
有两个错误:
直接赋值b[0]
而不调用push_back
或不事先在构造函数调用中初始化它。
另一行是
b[0].numList[2]
,因为您只调用了push_back()
两次,并且索引是基于0的。
最好是像这样直接初始化vector:
#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;
}
<<p> 生活例子/strong> 不能对空向量使用下标操作符赋新值。使用push_back
成员函数代替。
std::vector<ttt> b;
b.reserve( 3 );
//...
b.push_back( ttt() );
b.back().ID = 1;
//...
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)
虽然这看起来有点神秘,但一些经验建议检查push_back()
的this
参数是否已初始化。纵观代码,我们看到:
vector<ttt> b;
b.reserve(3);
b[0].ID = 1;
b[0].numList.push_back(3);
您已经告诉vector准备有3个元素,但是您从未向其添加任何ttt
对象。当你访问b[0]
时,你正在使用未初始化的内存(Valgrind不会抱怨分配给b[0].ID
,因为内存已经分配并且属于b
-但是调用push_back
试图读取vector
成员,这可能是随机垃圾)。
显而易见的解决方案是emplace_back()
(或以其他方式创建)b
的元素。
在vector上调用reserve()
时,它不会创建包含类型的任何实例。只为元素分配空间。因此,当您尝试访问向量中的这些位置时,您会得到未定义行为。必须先将元素压入vector容器,或者在对其进行读写操作之前,先使用vector<ttt> b(6);
之类的调用对其进行零初始化。
只编辑声明ttt
s向量的那一行,并删除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