-1

I'm new to C++. I have this code:

int main()
{
    vector<int> a = { 1,2,3,4,5,6 };  

    vector<int> b(&a[0], &a[5]);    // what's wrong?  Is it completely wrong this way?

    for (int i = 0; i < 6; i++) {
        cout << b[i] << endl;
    }
    return 0;
}

I know the right way. please tell me where is b[5] and why i can't access it in this code.

Exon
  • 315
  • 2
  • 9

3 Answers3

3

The end iterator is the one past the last item you want in the range. You could say &a[6], but you'd be better off using the container's built-in iterators like vector<int> b(a.begin(), a.end());.

Even better, vector<int> b {a}; uses the copy constructor so you don't have to fart around with iterators or pointers at all.

cHao
  • 84,970
  • 20
  • 145
  • 172
3
vector<int> b(&a[0], &a[5]);

This sort of construction uses the Iterator-based constructor for std::vector (which is capable of just using pointers, though this isn't recommended, since iterators encapsulate their implementation and possible behavior quirks, and are generally safer). The Iterator constructor takes two iterators, the beginning, and one-past-the-end. You're passing the beginning and the end, which means the new vector is constructed in a range one-less-than the size of the original.

If you're commited to this syntax, the correct way to write it would be

vector<int> b(a.begin(), a.end());

If you just intend to copy the vector, though, this is unnecessary. You should just copy it with the assignment operator:

vector<int> b = a; //b is now a copy of a, using its own memory

If you want to copy a subset of a vector, use the actual iterators:

vector<int> b(a.begin() + 2, a.begin() + 5);//Copies a[2], a[3], a[4] into a vector of size 3.
Xirema
  • 19,889
  • 4
  • 32
  • 68
1

Ranges in C++ are specified in the form

[first, last)

The closing parenthesis instead of square bracket means that acceptable values do not include the value last.

Thus in this declaration

vector<int> b(&a[0], &a[5]);

the acceptable range of pointers (iterators) is [&a[0], &a[5] ) that is the value pointed to by the pointer &a[5] will not be used in the initialization of the vector b. The vector will have only 5 elements equal to a[0], a[1], a[2], a[3] and a[4].

So using the magic number 6 in this loop

for (int i = 0; i < 6; i++) {
    cout << b[i] << endl;
}

results in undefined behavior.

You could write for example

for ( size_t i = 0; i < b.size(); i++ )
{
    std::cout << b[i] << std::endl;
}     

or just

for ( auto x : v ) std::cout << x << std::endl;

It is evidently that it would be simpler to initialize the vector b like

vector<int> b( a );

But if you want to specify some range of the vector a as an initializer of the vector b then you can write for example

#include <iterator>

//...

vector<int> b( a.begin(), std::next( a.begin(), 6 ) );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335