简体   繁体   English

在 C++ 中的向量中使用 push_back vs at

[英]Using push_back vs at in a vector in C++

Have a doubt in using vectors in C++.对在 C++ 中使用向量有疑问。 it is to do with the push_back method in the vector.它与向量中的 push_back 方法有关。 For the first program, i have used push_back to insert elements into the vector.对于第一个程序,我使用 push_back 将元素插入到向量中。 For the second program, i have used at( ) to insert elements into the vector.对于第二个程序,我使用 at() 将元素插入到向量中。

#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main ()
{
  std::vector<string> myvector (3);

  cout << "In main" << endl;
  for (unsigned i=0; i<myvector.size(); i++)
  {
    myvector.push_back("hi");  //Note: using push_back here.
  }
  cout << "elements inserted into myvector" << endl;

  std::cout << "myvector contains:" << endl;
  for (auto v: myvector)
     cout << v << endl;

  // access 2nd element
  cout << "second element is " << myvector[1] << endl;

  return 0;
}
Output:    
Hangs after entering main.    
$ ./a.out    
In main

whereas if I used myvector.at() to insert the elements like below, its fine.而如果我使用 myvector.at() 插入如下元素,则很好。

#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main ()
{
  std::vector<string> myvector (3);

  cout << "In main" << endl;
  for (unsigned i=0; i<myvector.size(); i++)
  {
    myvector.at(i) = "hi";  // using 'at' instead of 'push_back'
  }
  cout << "elements inserted into myvector" << endl;

  std::cout << "myvector contains:" << endl;
  for (auto v: myvector)
     cout << v << endl;

  // access 2nd element
  cout << "second element is " << myvector[1] << endl;

  return 0;
}

Output:
./a.out
In main
elements inserted into myvector
myvector contains:
hi
hi
hi
second element is hi
$

What is wrong with the way i have used push_back ?我使用 push_back 的方式有什么问题? This is one of the ways we insert elements into the vector, right.这是我们向向量中插入元素的方式之一,对吧。

The issue in this loop:这个循环中的问题:

for (unsigned i=0; i<myvector.size(); i++)
{
    myvector.push_back("hi");  //Note: using push_back here.
}

is that if you ever enter the loop, ie myvector is not initially empty, then each push_back will increase the size of the vector.是如果你曾经进入循环,即myvector最初不是空的,那么每个push_back都会增加向量的大小。 Since i is incremented once each time in the loop, it will never catch up to the size of the vector, and you end up with an infinite loop.由于i在循环中每次递增一次,它永远不会赶上向量的大小,最终会陷入无限循环。


.at() doesn't have this problem, since it only indexes into the vector, without ever changing its size. .at()没有这个问题,因为它只索引到向量中,而不会改变它的大小。 So long as the argument to at is a valid index, you can access this position without any issues.只要at的参数是有效索引,您就可以毫无问题地访问此位置。

The problem is that you push the elements in a loop that never stops:问题在于您将元素推入永不停止的循环中:

for (unsigned i=0; i<myvector.size(); i++)
{
   myvector.push_back("hi");  //Note: using push_back here.
}

After the first iteration the vector will have 4 elements and i will be 1 .第一次迭代后,向量将有4元素, i将为1 As you increment i by one in each iteration and myvector.size() also increases by one, the condition will never be false.当您在每次迭代myvector.size() i增加 1 并且myvector.size()也增加 1 时,条件永远不会为假。

std::vector::at on the other hand, does not add elements to the vector.另一方面, std::vector::at不会向向量添加元素。 Hence, after 3 iterations the loop ends.因此,在 3 次迭代后,循环结束。

The problem is in this line:问题出在这一行:

std::vector<string> myvector (3);

You are declaring a vector with 3 elements.您正在声明一个包含 3 个元素的向量。 In this case, those elements are empty strings.在这种情况下,这些元素是空字符串。

When you later do myvector.pushback("hi") You add elements to your vector.当您稍后执行myvector.pushback("hi")元素添加到您的向量中。 The previous empty string are still there in in front of your added string.之前的空字符串仍然在您添加的字符串前面。

To define an empty vector, you just do:要定义一个空向量,您只需执行以下操作:

std::vector<string> myvector;

and if you know you are going to add 3 elements you can also do如果你知道你要添加 3 个元素,你也可以这样做

std::vector<string> myvector;
myvector.reserve(3);

The purpose of reserve is to preallocate memory. reserve的目的是预分配内存。 This preallocated memory will not be part of your vector until you actually insert any new elements.在您实际插入任何新元素之前,此预先分配的内存不会成为您的向量的一部分。

Remember that std::vector is not supposed to behave like c -like arrays.请记住, std::vector不应表现得像c类数组。 The purpose of std::vector is to be resizable, so you don't need to decide up front how many elements you need, or keep track of its current used size. std::vector的目的是可调整大小,因此您无需预先决定需要多少个元素,或跟踪其当前使用的大小。

push_back adds a new element at the end of a vector . push_backvector的末尾添加一个新元素。 It increases the size and does not provide access to existing elements.它增加了大小并且不提供对现有元素的访问。

at() is to access an element of a vector . at()是访问vector的元素。 It does not increase the size of vector and does not add an element to it.它不会增加vector的大小,也不会向其中添加元素。 it is to read/write of an existing element.它是读取/写入现有元素。

So we can not compare these two with each other.所以我们不能将这两者相互比较。 Each does a different job.每个人都做不同的工作。

We can however compare operator[] with at() .然而,我们可以将operator[]at()进行比较。 The former does not throw out a range exception, cause it does not check, while the latter check out of bound and throws an exception when it should.前者不抛出范围异常,导致它不检查,而后者检查越界并在应该时抛出异常。

Other answers fully covered why the first code hangs so I am not repeating them here.其他答案完全涵盖了为什么第一个代码挂起,所以我不会在这里重复它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM