Aly
Aly

Reputation: 16255

How to randomly assign to vector in C++?

I am new to C++, and am continuously told to use std::vector instead of new[].

I am trying to achieve this functionality, in where I know the size of the vector and want to assign to it randomly (not sequentially).

However, when running this, my program terminates with no error output, so I am stumped.

vector<string> v1;
v1.resize(2);
v1.insert(v1.begin() + 1, "world");
v1.insert(v1.begin() + 0, "world");

cout << v1.at(1) << endl;

Upvotes: 13

Views: 1388

Answers (5)

Elliot Hatch
Elliot Hatch

Reputation: 1110

Like many have stated, you can can just use operator[] to reassign old values, given that you've already sized the vector or filled it with other values. If your array will always have a fixed size you can use std::array, which should provide a performance boost, at the sacrifice of the ability to resize the array or determine its size at runtime.

std::array<std::string,2> a1;
a1[0] = "world";
a1[1] = "world2";
std::cout<<a1.at(1)<<std::endl; //outputs world2

Note that the size must be static, so you can't do something like this:

int numStrings;
std::cin>>numStrings;
std::array<std::string,numStrings> a2; //ERROR

Unfortunately, I don't think there is any way of initializing an std::array without a default constructor, other than using an initialization list.

struct T
{
   T(std::string s):str(s){} //no default constructor
   std::string str;
}
std::array<T,2> a3 = {T(""), ""}; //you can use a conversion constructor implicitly

Obviously, this isn't practical if you want an array with a sizable number of objects.

Upvotes: 2

emartel
emartel

Reputation: 7773

To randomly assign

Simply use the index (obviously, validate that it's < size)

v1[index] = value;

To randomly insert (validate that index < size)

v1.insert(v1.begin() + index, value);

To sequentially insert at the end / append (no need for an index, your value will be inserted at the end of the vector)

v1.push_back(value);

If you plan on inserting many values, consider calling reserve() on your vector so that enough memory can be allocated to store all of your items, otherwise as you insert your data you may end up with many reallocation as the vector grows

Upvotes: 10

DanChianucci
DanChianucci

Reputation: 1175

Your Program is working correctly. Your error is in the logic of your code.

Insert doesn't change the string stored at index 1. It places a string at position 1, and moves all indexes after 1 to the right.

start               first insert            second insert 
("","")      ->   ("", "world, "")    ->  ("world","","world","")

So when you print v1.at(1) you are printing an empty string.

To fix the issue, you would want to use:

v1.at(1)="world"
v1.at(0)="world"

--or--

v1[1] ="world"
v1[0] ="world"

The two solutions are equivalent, however the second will not do any bounds checking. The first will throw an error if there is an out of bounds error. This shouldn't matter as long as you can gaurantee that you will never index out of bounds.

Upvotes: 6

Joseph Mansfield
Joseph Mansfield

Reputation: 110658

First you resize it to have two empty strings:

{"", ""}

Then you insert "world" before begin() + 1 or the 2nd element:

{"", "world", ""}

Then you insert "world" before begin() or the 1st element:

{"world", "", "world, ""}

Then you access the 2nd element with v1.at(1) and get the empty string.

Presumably, you don't want std::vector::insert which inserts new elements between existing elements. You want to do this as you would with arrays, with operator[]:

vector<string> v1(2);
v1[1] = "world";
v1[0] = "world";
cout << v1.at(1) << endl;

Upvotes: 12

john
john

Reputation: 8027

Don't give up, it's easier than that

vector<string> v1(2);
v1[1] = "world";
v1[0] = "world";

cout << v1[1] << endl;

vector::insert is for when you want to add items to your vector, Not when you want to replace ones that are already there, vector::insert changes the size of the vector in other words.

Upvotes: 19

Related Questions