C++ STL: three question about vectors

#include <iostream>
#include <vector>
using namespace std;

int main()
{

double array[5] = {3.45, 67, 10, 0.67, 8.99};
vector<double> vec;
vec.assign(array, array + 5);
vector<double>::iterator it;

*it = vec.front();
cout << *it << " ";
*it = vec.back();

// 1.0 Here I get Access denied.

it = &vec.front();
// 2 Here I got compiler error

it = vec.begin();
vec.insert(it, 3, 90);
cout << *it;
// 3. Here I can't use insert function.
    return 0;
}

Open in new window

Nusrat NuriyevAsked:
Who is Participating?
 
sarabandeCommented:
Iterators can be used to look like pointers, but they are not pointers.

iterators also may be pointers. actually in the early times of stl, vector<T>::iterator was indeed a simple pointer to T.

even nowadays you may use pointers for iterators if the container is a c array:

double dblarr[4] = { 0.1, 0.3, 1.2, -1.5 };

// use pointer to begin and pointer to end of dblarr to initialize a vector
std::vector<double> dblvec(&dblarr[0], &dblarr[4]);

Open in new window


the snippet show the use of a constructor of std::vector that has the following signature:

template<class _Iter>
		vector(_Iter _First, _Iter _Last,
			typename enable_if<_Is_iterator<_Iter>::value,
				void>:: type ** = 0) 

Open in new window


a pointer can be used as iterator if one of the following applies:

(1) the element the pointer is pointing to, is an array  element of the requested type
      (what is also the case for pointers to the internal array of std::string and std::vector)
(2) the iterator of the container is defined by a typedef of a pointer to template type
(3) the template iterator class used has a constructor that takes a pointer to template type as argument

(2) and (3) are dependent on the platform-specific stl implementation.

Sara
0
 
phoffricCommented:
In line 13, I would like you to go into your debugger and check out the value of it.
0
 
phoffricCommented:
For line 19, please review the return type of std::vector::front
http://www.cplusplus.com/reference/vector/vector/front/

and compare that type with the type of it.
0
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

 
phoffricCommented:
For line 23...
Well, many professionals on their job, when they get multiple problems in one compilation or build, will fix one or two issues and then rebuild. For this line, I would work on the first two problems, and from what you have learned, maybe you will be able to easily fix this problem.
0
 
sarabandeCommented:
*it = vec.front();
the statement is invalid. unlike to std::vector::begin std::vector::front doesn't return an iterator but a direct reference to the first vector element.

so, the right side of the assignment is double& .

the left operand of the assignment however is invalid as it tries to dereference an uninitialized iterator. actually the compiler should bring at least a warning. in any case the behavior at runtime cannot be predicted as it depends on the (arbitrary) value the variable it has.

1.0 Here I get Access denied.
as told, dereferencing an iterator variable which is pointing to nowhere will show odd behavior. one of that might be 'access denied' which i never experienced.

// 2 Here I got compiler error
as told std::vector::front returns a reference to double which cannot assigned to an iterator (what is a pointer to a vector element).

// Here I can't use insert function.
if you insert at begin using an iterator it that pointed to the first element, the 3 elements were inserted at front o fthe vector. because of that 'moving' operation the it points to a memory location which most likely was freed by the insert operation. so, the statement 'cout << *it;' tries to reference a variable it which is invalid.

note, an iterator is similar to a pointer. if you don't make sure that an iterator variable points to a valid container element, you don't can expect that the iterator variable can be used correctly.

Sara
0
 
Nusrat NuriyevAuthor Commented:
Phoffric,  Yes, this is a homework. The homework is for my students.  I'm a teacher of C programming language.
These questions requries a minute or above to answer for C++ expert.
However, it will be better if I spend time to investigate that by myself.

First of all, in line 13 , there is a mistake .
it's like
int n = 5;
int *pi;
*pi = n;

Open in new window

Iterator is just an address, so it must be pointed to some address.
instead of this
vector<double>::iterator it;

Open in new window

will be
vector<double>::iterator it = vec.begin();

Open in new window

0
 
Nusrat NuriyevAuthor Commented:
sarabande,
about 2-nd

For iterator manipulation, there are two functions of vector which come in handy: the front() function which returns an iterator to the first element in the vector, and the back() which returns an iterator to the last element in the vector.
http://www.codeproject.com/Articles/20930/The-complete-guide-to-STL-Part-Vector

Has it been changed since 2007?
0
 
phoffricCommented:
Line 13 - you are correct.

>> // 1.0 Here I get Access denied.
Well, what was the value of it on your machine?
Could it have been 0, which is not a good address?
0
 
phoffricCommented:
There is potentially a 4th problem, which if you find to be a problem could be interesting to discuss in another question.
0
 
sarabandeCommented:
Has it been changed since 2007?
no. the statement in the article is wrong. in the following code sample they have

it = &vec.front();
cout << *it << " ";
it = &vec.back();

Open in new window


what makes clear that front and back are returning a reference to the first respectively the last element. the iterator of stl-part takes the address of the return value. former implementations of stl were using simple pointers as iterators like it is for c-type arrays. newer implementations use a class type derived from std::iterator.

see http://www.cplusplus.com/reference/vector/vector/front/for more information.

Sara
0
 
phoffricCommented:
In my earlier post I wrote:
For line 19, please review the return type of std::vector::front
http://www.cplusplus.com/reference/vector/vector/front/
 and compare that type with the type of it.
From that link:

           reference front();
const_reference front() const;

Access first element

Returns a reference to the first element in the vector.

 Unlike member vector::begin, which returns an iterator to this same element, this function returns a direct reference.
Then &vec.front() is the address of that first reference (i.e., the address of a double). So &vec.front() type is double*, which is not an iterator type. Iterators can be used to look like pointers, but they are not pointers.
0
 
phoffricCommented:
For the 4th (unstated) problem, read this link
http://www.cplusplus.com/reference/vector/vector/insert/
and search on the string valid and read what it says in the source code example as well as the Iterator validity section.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.