簡體   English   中英

C ++將字符串放入字符串向量的結構中

[英]C++ Putting a string into a structure of vectors of strings

我在將字符串值放入“字符串向量結構”時遇到問題。 最簡單的可重現代碼如下:

#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,我使用下面的compile命令。

/usr/bin/g++ --std=gnu++0x -Werror -Wall -Wextra -Warray-bounds

真誠地,我們將非常感謝任何幫助。

有兩個錯誤:

直接分配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;
}

實例

您可能不會使用下標運算符為空向量分配新值。 請改用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);

你已經告訴向量准備有3個元素,但是你永遠不會添加任何ttt對象。 當你訪問b[0] ,你正在使用未初始化的內存(Valgrind不會抱怨對b[0].ID的賦值,因為內存已經被分配並且屬於b - 但是調用push_back嘗試讀取vector成員可能是隨機垃圾)。

顯而易見的解決方案是emplace_back() (或以其他方式創建) b的元素。

當您在向量上調用reserve()時,它不會創建包含類型的任何實例。 它只為元素分配空間。 因此,當您嘗試訪問向量中的這些位置時,會得到未定義的行為 你必須先將元素推入向量,或者用vector<ttt> b(6);類的調用對它們進行零初始化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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM