[英]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.