Thread: runtime error with vector

  1. #16
    Registered User
    Join Date
    Jul 2008
    Posts
    34
    Thanks alot guys this has helped a great deal! much appreciated

  2. #17
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Btw, for anyone interested, here's what I get with the undefined code:

    Inserting
    5
    10
    -33686019
    0
    459177
    Printing
    458760

    What I find curious is this:

    cout<<v[0]<<endl<<v[1]<<endl<<v[2]<<endl<<v[3]<<endl<<v[4]<<endl;
    cout<<"Printing"<<endl;
    cout<<v[4]<<endl;//v[4] has a value and its being printed which means [] operator has inserted it

    It prints the same element twice, yet got different results.
    And I suggest that anyone who thinks it is NOT undefined code, takes a look inside the ACTUAL code for vector.

    I took a look at the code and it looks like this:

    Code:
    	reference operator[](size_type _Pos)
    		{	// subscript mutable sequence
    
     #if _HAS_ITERATOR_DEBUGGING
    		if (size() <= _Pos)
    			{
    			_DEBUG_ERROR("vector subscript out of range");
    			_SCL_SECURE_OUT_OF_RANGE;
    			}
     #endif /* _HAS_ITERATOR_DEBUGGING */
    		_SCL_SECURE_VALIDATE_RANGE(_Pos < size());
    
    		return (*(_Myfirst + _Pos));
    		}
    _Myfirst is a pointer of type int*. Does that insert a value?
    If it does, then I don't see how.
    Blam! Rumor smashed. Operator [] does not insert.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #18
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Code:
    #include <iostream>
    #include <vector>
    
    int main()
    {
    	std::vector<std::string> v;
    	
    	//v.resize(1001);
    	v[1000] = "Some random string.";
    	std::cout << "v[1000] = " << v[1000] << std::endl;
    	
    	return 0;
    }
    Oh, look. This crashes for me. I'm shocked. I'm also being sarcastic.

    If it's not undefined, why does it crash?

  4. #19
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> I see little benefit in using at() since it obviously has more overhead.
    This would be a premature optimization, IMO, at least in most programs.

    >> The error message is not vague and the error is easy to fix.
    It's undefined behavior. The OP got lucky with an easy to understand error message because of his or her platform (which is probably doing range-checking on operator[] anyway meaning at() adds no overhead). It might appear to work but give incorrect data to your program, which is why I suggested that at() be considered.


    >> according to the original Code from te5la which uses break means he want to remove the
    >> first only so It doesnt need to care about all other matches.
    noobcpp, your iterator example did not break when it found a match, so either it is wrong because it doesn't follow the OP's use case or it is wrong because it fails to delete all values. Either way it is wrong (in fact, it could lead to accessing an iterator after end() which is also quite bad).

    And as has been noted vector does not insert when you use operator[] (although std::map does). Please be careful to not give such blatantly wrong information in the future, it can be very confusing for the person just looking for a simple answer.

  5. #20
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    Well.... to give new input to this passionate discussion: let's have a look at the "vector" header file! It's open source, so you can just look it up. (please do so, noobcpp!).
    Code:
          // element access
          /**
           *  @brief  Subscript access to the data contained in the &#37;vector.
           *  @param n The index of the element for which data should be
           *  accessed.
           *  @return  Read/write reference to data.
           *
           *  This operator allows for easy, array-style, data access.
           *  Note that data access with this operator is unchecked and
           *  out_of_range lookups are not defined. (For checked lookups
           *  see at().)
           */
          reference
          operator[](size_type __n)
          { return *(this->_M_impl._M_start + __n); }
    
          /**
           *  @brief  Subscript access to the data contained in the %vector.
           *  @param n The index of the element for which data should be
           *  accessed.
           *  @return  Read-only (constant) reference to data.
           *
           *  This operator allows for easy, array-style, data access.
           *  Note that data access with this operator is unchecked and
           *  out_of_range lookups are not defined. (For checked lookups
           *  see at().)
           */
          const_reference
          operator[](size_type __n) const
          { return *(this->_M_impl._M_start + __n); }
    (ps: this also should be stated in the Doxygen documentation of STL)

    And this is what "at()" does:
    Code:
          /// Safety check used only from at().
          void
          _M_range_check(size_type __n) const
          {
    	if (__n >= this->size())
    	  __throw_out_of_range(__N("vector::_M_range_check"));
          }
    And finally, tratatatata............ the function "at()" :
    Code:
          /**
           *  @brief  Provides access to the data contained in the %vector.
           *  @param n The index of the element for which data should be
           *  accessed.
           *  @return  Read/write reference to data.
           *  @throw  std::out_of_range  If @a n is an invalid index.
           *
           *  This function provides for safer data access.  The parameter
           *  is first checked that it is in the range of the vector.  The
           *  function throws out_of_range if the check fails.
           */
          reference
          at(size_type __n)
          {
    	_M_range_check(__n);
    	return (*this)[__n]; 
          }
    
          /**
           *  @brief  Provides access to the data contained in the %vector.
           *  @param n The index of the element for which data should be
           *  accessed.
           *  @return  Read-only (constant) reference to data.
           *  @throw  std::out_of_range  If @a n is an invalid index.
           *
           *  This function provides for safer data access.  The parameter
           *  is first checked that it is in the range of the vector.  The
           *  function throws out_of_range if the check fails.
           */
          const_reference
          at(size_type __n) const
          {
    	_M_range_check(__n);
    	return (*this)[__n];
          }
    Now guess what: "reference" and "const_reference" are typedefs for allocators:
    Code:
          typedef typename _Tp_alloc_type::reference         reference;
    which means simply that one can write an element with the function "at()" (again erroneous information, noobcpp!)

    ps: Isn't this poetry at it's most beautiful... :-)

  6. #21
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> let's have a look at the "vector" header file
    Of course, that's just one implementation. The final say is the standard, but this is such a simple and obvious point that everybody but noobcpp agrees on that I don't plan to look up the relevant text.

  7. #22
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    >> I see little benefit in using at() since it obviously has more overhead.
    This would be a premature optimization, IMO, at least in most programs.
    Yes after posting that I realized this argument was not the best and it's not exactly what I was trying to say. By no means would extra at()'s hurt performance and not all apps even care about top performance. So I will certainly retract this statement and restate it as - I prefer to use array access but probably have no good reason for doing so other than pure habit.

    >> The error message is not vague and the error is easy to fix.
    It's undefined behavior. The OP got lucky with an easy to understand error message because of his or her platform (which is probably doing range-checking on operator[] anyway meaning at() adds no overhead). It might appear to work but give incorrect data to your program, which is why I suggested that at() be considered.
    I think my point was the root of the problem was not necessarily the use of the array access operator but it was the misuse of it - IE: using it with an out of bounds index. Using at() would ensure you were in-bounds but I guess I'm coming from the mindset of you should know if you are in bounds or not. So the bottom line is this is a complete misuse of size() and of vector. I also don't want to project the notion that using at() is more valid than using array access or vice versa b/c both those arguments are quite absurd. It comes down to a choice on the programmer's part and if he/she uses their chosen method correctly they should have no troubles. I am certainly not condoning the use of code that produces undefined behavior. In the end I think most of us, minus a few, are saying the same thing.
    Last edited by VirtualAce; 07-15-2008 at 08:43 PM.

  8. #23
    Registered User
    Join Date
    Jun 2007
    Posts
    219
    I dont want to argue
    Quote Originally Posted by MacGyver View Post
    Code:
    #include <iostream>
    #include <vector>
    
    int main()
    {
    	std::vector<std::string> v;
    	
    	//v.resize(1001);
    	v[1000] = "Some random string.";
    	std::cout << "v[1000] = " << v[1000] << std::endl;
    	
    	return 0;
    }
    Oh, look. This crashes for me. I'm shocked. I'm also being sarcastic.

    If it's not undefined, why does it crash?
    Its a vector not a Map so it must mantain a sequence and when 0, 1, 2 ..... is not present you cnt insert an element on 1000 so it crashed.
    it can also happen that it crashed cause it tried to insert but failed.

    PLESE READ THE FULL POST

    But in most of the cases it inserts or at least it tries to insert. If one is stuck to say undefined behaviour Cant we put
    "trying to inserting an Item and failing" and
    "successfully Inserting an Item" and
    "Wrongly inserting an Item" and
    "inserting 0" and
    "inserting junk" and
    "crashing if jumped too far away indexes"
    all this posibilities together in the list of undefined behaviours ??

    However in vector its numarically and sequentialy indexed where as in map its not and in case of map's operator[]() it inserts a new element on the non existing node. (which is stated in documentation)
    and so in case vector also it tries to insert which leads undefined befaviour

  9. #24
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    noobcpp: Just on the off hand that yet one more pseron telling you that you are wrong will make a difference:
    The [] operator for a vector does not insert - EVER!!!
    The [] operator for a map does insert if the item does not already exist.
    The push_back method for a vector will insert one more item at the end of the vector.

    If you don't want to argue then stop posting nonsense. Of course people will disagree with false statements. It's in your best interests to do some research, realise you were wrong, swallow your pride, and actually learn something. That is if you'd perfer to stop making yourself look stupid.
    Last edited by iMalc; 07-16-2008 at 12:47 AM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  10. #25
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Again, vector does not insert. Ever.
    We have showed you two possible implementations, of which neither tried to insert anything.
    The standard says it's undefined, because access an out-of-bounds element is undefined.
    On other other hand, Microsoft's code also looks for out-of-range and throws or raises an assert if out-of-bounds happens because the standard does not say what happens if you do out of bounds.

    However, if you think that operator [] will insert, you are fatefully mistaken. We will most likely (99&#37; sure) that we will NEVER see such an implementation.

    It tries to access an out-of-bounds element, which leads to undefined behavior. That's all.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #26
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> I guess I'm coming from the mindset of you should know if you are in bounds or not.
    Understood. I honestly don't use at() myself. However, for someone having trouble knowing if they are in bounds or not, then it can be a good tool with few (if any) drawbacks. I think ideally I would move to using at() myself for non-performance critical operations, but I'm too stuck in the C style array habit to make the change.

  12. #27
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by noobcpp View Post
    But in most of the cases it inserts or at least it tries to insert.
    No. It doesn't.

    Oh, and btw.... as far as vector's go, "insert" is not the same as "trashes arbitrary memory in an undefined manner."

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. can some one please tell me the cause of the error ?
    By broli86 in forum C Programming
    Replies: 8
    Last Post: 06-26-2008, 08:36 PM
  2. syntax help?
    By scoobygoo in forum C++ Programming
    Replies: 1
    Last Post: 08-07-2007, 10:38 AM
  3. Vector class
    By Desolation in forum C++ Programming
    Replies: 2
    Last Post: 05-12-2007, 05:44 PM
  4. Need some help/advise for Public/Private classes
    By nirali35 in forum C++ Programming
    Replies: 8
    Last Post: 09-23-2006, 12:34 PM
  5. Certain functions
    By Lurker in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2003, 01:26 AM