Solved

C++ vector manipulation

Posted on 2014-01-23
6
666 Views
Last Modified: 2014-01-31
hi

i have a vector to which i want to add elements at random places. (I only say random because the act of insertion is not serial or sequential , rather it is formulaic.)

I have a vector defined like so:
std::vector<int> i;
std::vector<int>::iterator  begin=i.begin();


When I add i want to say something like this:
i.insert(begin+offset,myvalue);


However, if i have an empty i to begin with, so the iterator begin is a bad pointer.

How can i store the correct begin position for an empty vector?

i guess i could check to see if the vector was empty, add the first element, get begin to point to the first element etc. But i think this approach is inelegant. Can I somehow do things in the approach mentioned above?
0
Comment
Question by:LuckyLucks
6 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 39805188
>>However, if i have an empty i to begin with, so the iterator begin is a bad pointer.

Not really. it is a 'pesudo iterator', such as 'vector::end()'. Even with an empty map, you can always use

i.insert(i.begin()+offset,myvalue);

Open in new window


You just can't use it as 'begin=i.begin();' if 'i' is empty and use it further.
0
 
LVL 33

Assisted Solution

by:sarabande
sarabande earned 250 total points
ID: 39805866
you cannot add at position i if the vector has not already i elements.

so for an empty vector the statement

i.insert(i.begin()+offset,myvalue);

Open in new window

would throw an exception if offset is greater 0.

note, the iterator end() is a pseudo iterator only when the vector is empty and no internal array exists. in all other cases it points to a real address one slot behind the last element.

because of that you also could use pointers to a  c array when a function requires iterators:

std::string arr[4]  = { "ABC", "DEF", "GHI", "JKL" };
std::string * f = std::find(&arr[0], &arr[4], "XYZ");
if (f != &arr[4])
{
     // string found
      ... 

Open in new window


note, in the above sample code &arr[4] is an invalid pointer as it points to non-allocated memory. however, the address is not invalid but well defined.

Sara
0
 

Author Comment

by:LuckyLucks
ID: 39822136
I am getting Debug Assertion failed

at

Expression ("this->_Has_container()",0)

in the vector.h file (see line _SCL_SECURE_VALIDATE....

_Myt& operator+=(difference_type _Off)
            {      // increment by integer
            _SCL_SECURE_VALIDATE(this->_Has_container());
            _SCL_SECURE_VALIDATE_RANGE(
                  _Myptr + _Off <= ((_Myvec *)(this->_Getmycont()))->_Mylast &&
                  _Myptr + _Off >= ((_Myvec *)(this->_Getmycont()))->_Myfirst);
            _Myptr += _Off;
            return (*this);
            }
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 86

Expert Comment

by:jkr
ID: 39822209
Using which code? At which line of that?
0
 
LVL 33

Expert Comment

by:sarabande
ID: 39823379
the assertion is because you tried to access the vector beyond its current size. for example if the vector has two elements and you try to access the 3rd element. or if you want to insert with offset 10 but the vector has only 8 elements.

if you want to have a vector which automatically grows if you insert beyond its current size(creating 'empty' elements between), you need to do like

bool MyClass::insertWithGrow(std::vector<MyType> & v, const MyType & mt, int offset)
{
     if (offset < 0) return false;
     if (offset > (int)v.size())
     {
           v.resize(offset);   // grow the vector before inserting
     }
     v.insert(v.begin()+offset, mt);
     return true;
}

Open in new window


Sara
0
 
LVL 22

Accepted Solution

by:
ambience earned 250 total points
ID: 39823382
In general, it is a bad idea to store stl iterators, unless there is a really good reason for that and you really know what you are doing. For a vector, you can just use the indexer or i.begin() whenever needed.

STL iterators (at least for VC) use internal mechanism like container proxies to invalidate iterators whenever a container mutates (such as when new items are added). This is extra baggage in debug mode with the benefit that you trap errors easily and write safe code. For all practical purposes, as a general DESIGN principle of STL, you should not consider an iterator to be valid after mutating the container.

The following code throws an exception, because the vector has mutated - invalidating the iterator - even though, logically, the iterator should still be able to insert at head

	
        std::vector<int> i;
	i.resize(10);
	
	std::vector<int>::iterator  begin = i.begin();
	i.resize(100); // comment this line and it works
	i.insert(begin, 10);

Open in new window

0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

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…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
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.

830 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