?
Solved

C++ vector manipulation

Posted on 2014-01-23
6
Medium Priority
?
790 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 35

Assisted Solution

by:sarabande
sarabande earned 1000 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
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
LVL 86

Expert Comment

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

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 1000 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

Take Control of Web Hosting For Your Clients

As a web developer or IT admin, successfully managing multiple client accounts can be challenging. In this webinar we will look at the tools provided by Media Temple and Plesk to make managing your clients’ hosting easier.

Question has a verified solution.

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

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
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 viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

593 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