Solved

Using vector.begin() outside of range.

Posted on 2008-06-16
11
194 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
>> 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
Comment Utility
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
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
Comment Utility
wow, I must have been typing very slow lol. Sorry.
0
 
LVL 3

Author Closing Comment

by:Unimatrix_001
Comment Utility
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
Comment Utility
Hehe, sorry Infinity - just a bit slow there. Thanks anyways mate. :)
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
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
Comment Utility
>> 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

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

772 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

12 Experts available now in Live!

Get 1:1 Help Now