Solved

Using vector.begin() outside of range.

Posted on 2008-06-16
11
195 Views
Last Modified: 2010-04-21
Hello,

temp.insert(temp.begin(), pile.begin()+3-5, pile.end());

Will this crash, or will the "pile.begin()+3-5" be calculated to just pile.begin()? Likewise, if I tried to do pile.end()+5, will that calculate to pile.end()?

Thank you,
Uni
0
Comment
Question by:Unimatrix_001
  • 4
  • 4
  • 3
11 Comments
 
LVL 40

Expert Comment

by:evilrix
ID: 21792201
If you try to perform iterator arithmetic and the result exceeds the end you'll get undefined behavior if you then try to manipulate the element that the result refers to ... this is the same as if you performed pointer arithmetic and tried to access beyond the end of an array. Your result must fall within the begin() to end() range of the vector before you can use it safetly.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 21792212
Visual Studio will try and check this for you if _SECURE_SCL   is defined as 1

http://msdn.microsoft.com/en-us/library/aa985896(VS.80).aspx
_SECURE_SCL  
 

Defines whether Checked Iterators are enabled. If defined as 1, unsafe iterator use causes a runtime

error. If defined as 0, checked iterators are disabled. The exact behavior of the runtime error depends

on the value of _SECURE_SCL_THROWS. The default value for _SECURE_SCL is 1, meaning checked iterators

are enabled by default.
 

To enable checked iterators, set _SECURE_SCL to 1:

#define _SECURE_SCL 1
 

To disable checked iterators, set _SECURE_SCL to 0:

#define _SECURE_SCL 0

Open in new window

0
 
LVL 3

Author Comment

by:Unimatrix_001
ID: 21792222
Hm, is there anyway to bound the iterator to .begin and .end so that it is impossible to exceed them with any iterator arithmetic?
0
 
LVL 40

Accepted Solution

by:
evilrix earned 500 total points
ID: 21792269
>> is there anyway to bound the iterator to .begin and .end so that it is impossible to exceed them
Not that I know of, no.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 21792285
Rather than performing the arithmetic directly on the iterator why don't you perform it as number arithmetic and make sure the result is within v.size() before you try and add it to c.begin()? Quick example...

if(pile.size () >= 3.5)
{
   temp.insert(temp.begin(), pile.begin()+3-5, pile.end());
}
else
{
   //oops
}
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 53

Expert Comment

by:Infinity08
ID: 21792302
You can only increment an iterator if the iterator is dereferenceable.
You can only decrement an iterator if the resulting iterator would be dereferenceable.

past-the-end iterators are not guaranteed to be dereferenceable.

Since vector iterators are random access iterators, the operator+ and operator- are also defined for it, so you can add (or subtract) an integer value to (from) it. However, the result is only valid if it follows the above rules (by applying the increment/decrement operator n times).

In all other cases, the result is undefined. So, more specifically :


>> pile.begin()+3-5

is undefined


>> pile.end()+5

is undefined (it might work if the past-the-end iterator is dereferenceable, but there's no guarantee)


So, on some platforms, it might work (depending on how the C++ standard is interpreted), but there's no guarantee.


For example, with gcc, the following code crashes :
#include <iostream>

#include <vector>
 

int main(void) {

  std::vector<int> values;

  std::vector<int>::iterator it = values.begin() - 1;

  std::vector<int>::iterator it2 = values.end() + 1;

  

  std::cout << *it << std::endl;          // CRASH !!!

  std::cout << *it2 << std::endl;         // CRASH !!!
 

  return 0;

}

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 21792303
wow, I must have been typing very slow lol. Sorry.
0
 
LVL 3

Author Closing Comment

by:Unimatrix_001
ID: 31467536
Hm... That's a shame, thanks anyway. I was rather hoping to avoid having to check the bounds before doing it, but if that's the only way...
0
 
LVL 3

Author Comment

by:Unimatrix_001
ID: 21792318
Hehe, sorry Infinity - just a bit slow there. Thanks anyways mate. :)
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 21792321
Maybe I should have actually filled the vector with something heh. The fact that the following code doesn't crash is merely due to the implementation of iterators as gcc used. But again, there's no guarantee this code won't crash for another compiler.
#include <iostream>

#include <vector>
 

int main(void) {

  std::vector<int> values(5);

  std::vector<int>::iterator it = values.begin() - 1;

  std::vector<int>::iterator it2 = values.end() + 1;

  

  std::cout << *it << std::endl;         // no crash

  std::cout << *it2 << std::endl;        // no crash
 

  return 0;

}

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 21792326
>> Hehe, sorry Infinity - just a bit slow there. Thanks anyways mate. :)

No worries ;) I'll have to be faster next time heh
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

896 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now