Solved

C++ vector manipulation

Posted on 2014-01-23
6
629 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
Comment Utility
>>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 32

Assisted Solution

by:sarabande
sarabande earned 250 total points
Comment Utility
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
Comment Utility
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
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 86

Expert Comment

by:jkr
Comment Utility
Using which code? At which line of that?
0
 
LVL 32

Expert Comment

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

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
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…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

771 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

10 Experts available now in Live!

Get 1:1 Help Now