简体   繁体   中英

Two ways to assign elements of std::vector

As far as I am aware, one can assign elements to a std::vector in two ways:

vec[i] = value

vec.push_back(value)

However the first method doesn't appear to have an effect on vec.size() , and is also overwritten by subsequent calls to vec.push_back() . A minimal example to demonstrate:

#include <iostream>
#include <vector>

int main()
{
    std::vector<unsigned char> things;
    things.reserve(2);

    things[0] = 'a';
    std::cout << "Size after inserting a: ";
    std::cout << things.size() << std::endl;

    things.push_back('b');
    std::cout << "Size after inserting b: ";
    std::cout << things.size() << std::endl;

    std::cout << "Contents: ";
    for (int i=0; i<2; i++)
    {
        std::cout << things[i] << std::endl;
    }

    return 0;
}

The output of this program is:

Size after inserting a: 0
Size after inserting b: 1
Contents: b

So could someone please explain:

  1. Why is the size 0 even after we insert 'a' ?

  2. Why does things.push_back('b') overwrite the 'a' ?

Note: I am using unsigned char because I've adapted this code from a program I'm writing that involves manipulating this type.

Thanks in advance.

reserve doesn't actually change the size of the vector. It only changes the capacity of the vector - that is different from its actual size (see here for an explanation of what it actually is). So your call of things[0] = 'a'; is past the size of the vector as it still has size 0 and therefore undefined behavior.

If you call resize instead, you get this:

Size after inserting a: 2
Size after inserting b: 3
Contents: a

Now the vector contains a 'a' , a '\\0' and a 'b' . The '\\0' is there because that's the default value of unsigned char , so things.resize(2); leaves the vector with two of those before you change one to an 'a' .

  1. You didn't insert it, you assigned to an element that doesn't exist. This has undefined behaviour. Assigning does not extend the vector.
  2. Because the vector was empty, push_back added the first element.

One more info

std::vector<unsigned char> things;
things.reserve(2);

Below assignment, without checking the bounds of vector it will write to memory pointed by things[0]. This operation never fails but causes undefined behavior due the corruption of memory.

things[0]    = 'a';  // 1

Below assignment check bounds of vector before writing to memory pointed by things[0]. It fails if the index is not within the bound of vector and throws 'std::out_of_range' exception.

things.at(0) = 'a'   //2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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