将字符串放入字符串的向量结构中



我有一个问题,把字符串值放入"字符串的向量结构"。最简单的可复制代码如下:

#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

最新更新