What happens is that std::vector
is a class that, internally, makes use of an array, but has many more things.
A raw array like the one you use in the first example has only the memory needed to store the number of elments you are asking for:
| 0x100 | 0x101 | 0x102 | 0x103 | 0x104 | 0x105 | 0x106 |0x107 |
int array[2] -> | array[0] | array[1] |
However, the class std::vector
is more complex (and hence it is much more versatile than a raw array.) The standard does not specify how this class should be implemented, in the case of MSVC2015 we can find a structure like this one ( simplifying):
template<class _Ty, class _Ax = allocator<_Ty> >
class vector
{
typedef typename _Ax::template rebind<_Ty>::other _Alty;
typedef typename _Alty::pointer pointer;
pointer _Myfirst; // pointer to beginning of array
pointer _Mylast; // pointer to current end of sequence
pointer _Myend; // pointer to end of array
_Alty _Alval; // allocator object for values
};
That basically comes to say that, for this particular compiler, the class std::vector
manages three pointers (start of the array, end of sequence and end of the array) and an object for memory management.
std::vector
uses pointers internally because, unlike a raw array, it uses dynamic memory. This explains why you can start adding elements to the vector without worrying about its size:
std::vector<int> datos;
// ...
datos.push_back(10);
datos.push_back(20);
datos.push_back(30);
// ...
While with a raw array you have to be very careful not to exceed its limits:
int array[10];
array[10] = 123; // <<--- ups!!!
It is clear that a raw array and std::vector
, although they can be used with the same syntax, look like a churro to a space rocket.
Now, answering your questions ...
If I try the name, as references ... I print different addresses
Indeed:
-
&myvector
is going to return the memory address where the object std::vector
is found.
-
&myvector[0]
returns the memory address where the first element of the vector is located. As the class std::vector
makes use of dynamic memory, this memory position will hardly coincide with that obtained in the previous point.
Working with vectors, is there any way of knowing where element 0 is, by the name of the vector?
And why do you want to know that information exactly?
If you need to modify only that position you can get it as you have done in your example:
'&myvector[0]'
But using the vector in this way implies certain totally unnecessary risks:
-
If you need to modify elements of the vector, the easiest and safest way is to pass the vector as a reference:
void func(std::vector<int> & myvector)
{
// ...
}
-
The class vector
is able to resize the memory it manages in a fully automatic and transparent way for the user. If you access their memory locations as you intend and the vector is resized you can end up accessing memory that does not belong to you.
-
To move around the vector, the most common is to use the iterators:
std::vector<int> myvector = funcionQueGeneraUnVector();
// Hasta C++11
for( std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it )
{
// ...
}
// C++11 en adelante
for( auto it = std::begin(myvector); it != std::end(myvector); ++it )
{
// ...
}
Iterators can be used in a thousand different ways:
std::vector<int> datos = { 1, 4, 2, 7, 5, 9, 3, 0 };
// Localizamos la posicion del numero 7
auto it = std::find(std::begin(datos),std::end(datos),7);
// Imprimimos dicho valor, despues el anterior y finalmente el posterior
std::cout << *it << *(it-1) << *(it+1) << '\n';
// Eliminamos el numero 7 del vector
datos.erase(it);
// Imprimimos el vector sin el 7
for( int numero : datos )
std::cout << numero << ' ';
This last statement returns the following error:
..\YourOtherClass_test.cpp:40:9: error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'std::vector<int>')
That's because does not exist an overload of the insertion operator on the class ostream
that accepts an object of type std::vector
. However, that is something that has a solution:
std::ostream& operator<<(std::ostream& os, std::vector<int> const& v)
{
for( int dato : v )
os << dato << ' ';
return os;
}
std::vector<int> myvector={1,2,3,4};
cout<<myvector<<endl; // Imprime 1 2 3 4