C ++如何用字符串填充未定义大小的向量?

时间:2016-09-24 23:25:42

标签: c++ vector

我试图将用户输入的字符串拆分并逐个字符地存储在矢量中。但是,当输入并输入字符串时,我收到此错误:

  

Debug Assertion失败!

     

程序:C:\ WINDOWS \ SYSTEM32 \ MSVCP140D.dll

     

文件:c:\ program files(x86)\ microsoft visual studio 14.0 \ vc \ include \ vector

     

行:1234

     

表达式:向量下标超出范围

我已经尝试过研究载体,看看我是否正确实现了它,但从我看来我看来是这样。

这是我的代码:

#include <iostream>
#include <string>
#include <cstdlib>
#include <time.h>
#include <vector>

using namespace std;

void rovarspraket(); //declaration because I like to put my functions after main()

int main() {
    rovarspraket(); //function call

    system("pause");
    return 0;
}

void rovarspraket() { //the function
    string sText; //string that will be inputted
    vector<string> vText; //vector that sText will go into

    cout << "Input text to be encoded to Rovarspraket: ";
    cin.ignore();
    getline(cin, sText); //gimme dat sText

    cout << "\n\n"; //pretty formatting, just ignore

    for (int i = 0; i < sText.length(); ++i) {
        vText[i] = sText[i]; //slap that character into the vector
        cout << vText[i] << endl; //just to test what was actually happening
    }
}

4 个答案:

答案 0 :(得分:1)

Sam Varshavchik已经说过了,我想稍微解释一下。但基本上你试图将矢量的第一个元素分配给其他东西,但问题是你的矢量是空的,所以没有要分配的元素!使用.push_back()将元素添加到向量的末尾。所以你的&#34; for&#34;循环应该如下所示:

for (int i = 0; i < sText.length(); ++i) {
    vText.push_back(sText[i]);
    cout << vText[i] << endl;
}

答案 1 :(得分:1)

你的问题是“未定义大小的矢量”,但是

std::vector<std::string> vText;

没有未定义的大小:它的大小为

#include <iostream>
#include <vector>
#include <string>

int main() {
    std::vector<std::string> v;
    std::cout << v.size() << "\n";
}

有明确定义的行为 - 它打印0:http://ideone.com/JW2LDH

您的代码中发生的事情是您正在执行超出当前数据末尾的访问:

std::vector<std::string> v;
v[0] = "";  // Undefined Behavior: v has size 0

有几种方法可以向向量添加数据:

std::vector::push_back
    v.push_back("hello");

这会将数据大小增加一个,而default会构造新元素,然后将参数复制到其中。

std::vector::emplace_back (since c++11)
    v.emplace_back("hello");

与push_back类似,但不是default-ctor + copy就是就地创建新元素。

std::vector::resize(N);  // allocates and default-ctors elements
    v.resize(5);
    v[0] = "hello";
    v[4] = "world";
    v[5] = "";  // UB, beyond end of data

将数组大小增大或缩小为N.在所有增长情况下,它可能会导致新分配以及所有现有元素的结果副本进入新空间。

为避免这种情况,您可以使用std::vector::reserve(N)提前为N个元素分配空间 - 这可以帮助提高push_back / emplace_back的性能。

std::vector::insert(iterator, value);
    v.insert(v.begin(), "hello");  // at front
    v.insert(v.begin() + 1, "world");  // after 'hello'
    std::cout << v[0] << v[1];  // "helloworld"
    std::cout << v[2];  // UB, beyond end of data

在给定的迭代器位置插入元素。

答案 2 :(得分:0)

初始化矢量时,您会给它一个默认空间(我认为保留了8个对象的空间)。

如果你传递一个足够短的字符串,可能不会发生任何坏事,但如果字符串长度大于向量中保留的对象,你基本上会尝试分配存在的东西(字符串的字符)对于那些不存在的东西(该向量中的空间)。

你可以做的一件事是:

app_db: {
"host": "127.0.0.1",
"port": 27017,
"database": "test",
"name": "app_db",
"username": "youruser",
"password": "yourpassword",
"connector": "mongodb",
"ssl":true,
"server": {
  "auto_reconnect": true,
  "reconnectTries": 100,
  "reconnectInterval": 1000,
  "sslValidate":false,
  "checkServerIdentity":false,
  "sslKey":fs.readFileSync('path to key'),
  "sslCert":fs.readFileSync('path to certificate'),
  "sslCA":fs.readFileSync('path to CA'),
  "sslPass":"yourpassphrase if any"

} 

或(这是理想的)

for (int i = 0; i < vText.size(); ++i) {
    vText[i] = sText[i];
    cout << vText[i] << endl;
} // So you never exceed vector's allocated space.
  // Beware tho, that string might not be fully copied into the vector.

你也可以用巨大的空间差来初始化矢量,但这是浪费资源:

for (int i = 0; i < sText.length(); ++i) {
    vText.push_back(sText[i]);
    cout << vText[i] << endl;
}

答案 3 :(得分:0)

STL中的向量是表示一种&#34;动态数组&#34;的对象。因此,只需初始化,它们就不会为其数据保留任何内存。如果您事先知道大小(但由于某种原因,您不想使用数组),您可以先使用以下内容初始化向量:

std::vector<std::string> vect;

然后在其上调用reserve()以保留一定数量的元素:

vect.reserve(4);    // Reserve 4 "memory space" for elements

不要忘记访问向量元素的唯一可移植方法是使用迭代器(很容易用C ++ 11中的auto关键字),例如:

for (auto iter = vect.begin(); iter != vect.end(); iter++) {
    *iter = valueToAssignToArray;
}

否则,正如其他人所建议的那样,您只需使用push_back方法调用要添加到向量的对象的复制构造函数(在本例中为{{1的复制构造函数) ,这意味着字符串被复制到向量)或string方法直接调用对象的构造函数(在将对象添加到向量之前无需初始化对象)。