1

Trying to make vector from part(5 elements) of c-array.

const static int size = 10;
cout << "vector from C-array: " << endl;
int ia[size] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
vector<int> vi2(ia, ia + size-5);

But when I try enumerate vector items using whole length of c-array I got all items like vector would be initialized like vector<int> vi2(ia, ia + size-5); . No exception or error that it goes out of range.

    for(int i = 0; i < size; i++) {
    cout << i << ":" << vi2[i] << " ";
}

In output:

0:1 1:2 2:3 3:4 4:5 5:6 6:7 7:8 8:9 9:10 

Why vector initialization is using second param that describes pointer to array end if it doesn't uses it?

vico
  • 17,051
  • 45
  • 159
  • 315
  • Have you checked `vi2.size()`? It should give `5`, and if it does, accessing beyond the 5th element will give you undefined behaviour. – Joseph Mansfield Dec 21 '13 at 16:53
  • `vi2` _is_ using that end of array pointer. _You_ are the one who is ignoring it and indexing it all the way to `size`. – Shahbaz Dec 21 '13 at 16:54
  • If you want an exception to be thrown, use `vector::at()` instead of `vector::operator[]`.\ –  Dec 21 '13 at 16:57
  • The output shown is *possible*, like it's possible to get an asteroid in the head. It is however just as unlikely. Can you post a **complete but minimal** example that exhibits the claimed behavior. – Cheers and hth. - Alf Dec 21 '13 at 17:05
  • BTW: If you want five elements, write `vector vi2(ia, ia + 5);` instead of `vector vi2(ia, ia + size-5);`. In this case, it doesn't matter, because size-5 == 5, but the first way indicates that you want the first five, and the second indicates you want all but the last five. – leewz Dec 21 '13 at 17:51

4 Answers4

3

You are accessing your vector out of bounds. This is undefined behaviour. There is no requirement that an exception be thrown.

You must not go beyond vi2.size()-1.

for(int i = 0; i < vi2.size(); ++i) 
{
  std::cout << i << ":" << vi2[i] << " ";
}
TobiMcNamobi
  • 4,687
  • 3
  • 33
  • 52
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
2

The [] operator doesn't do any bounds checking (similarly to the [] operator in C and C++ which works with raw arrays).

If you want an exception to be thrown, then use the at member function:

std::vector<int> v { 1, 2, 3, 4, 5 };
int invalidInt = v.at(5); // hell breaks lose, says the runtime
1

C++ doesn't throw an exception the way Java does if you access an out of bounds index. It's undefined behavior, and you simply must not do it.

for(int i = 0; i < vi2.size(); i++) {
    cout << i << ":" << vi2[i] << " ";
}

See A Guide to Undefined Behavior in C and C++:

In a safe programming language, errors are trapped as they happen. Java, for example, is largely safe via its exception system. In an unsafe programming language, errors are not trapped. Rather, after executing an erroneous operation the program keeps going, but in a silently faulty way that may have observable consequences later on.

Community
  • 1
  • 1
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
1

If you really want an exception to be thrown when you're out of bounds, use .at():

for(int i = 0; i < size; i++) {
    cout << i << ":" << vi2.at(i) << " ";
}

That being said, better use the actual size of vi2 (vi2.size()) instead.

Zeta
  • 103,620
  • 13
  • 194
  • 236