std::vector<int> example[1024];
How can I access all 1024 "examples" and their vector elements?
When I try example[0] it is the same like example.at(0) and I access the the first element in a vector...
I want to do the same as with variables:
int variable[1024]; ... but instead of an integer there is a vector...
It is not really clear what do you want to accomplish, but generally std::vector works pretty like classic C++ array.
And all the elements go one after another in memory, so you can do this for example
std::vector<int> test(1024);
test[0] = 1;
test[1] = 4;
test[2] = 8;
int* first = &test[0];
std::cout << "First is " << *first << std::endl;
int* second = first + 1;
std::cout << "Second is " << *second << std::endl;
Related
I am creating std::list of struct elements. With a certain criterion, I want to store addresses of few elements (because those addresses don't change(?)) from the list into std::vector for quick access in another usage. An example of the things is given below
#include <iostream>
#include <vector>
#include <list>
struct Astruct{
double x[2];
int rank;
};
int main(int argc, char *argv[]) {
std::list<Astruct> ants;
std::vector< Astruct* > ptr;
for (auto i = 0; i != 20; ++i) {
Astruct local;
local.x[0] = 1.1;
local.x[1] = 1.2;
local.rank = i;
// put in list
ants.push_back(local);
// store address of odd numbers
// rather than temperory address, permenent address from list is needed
if(local.rank %2 == 0) ptr.push_back(&local);
}
// print the selected elements using addresses from the list
for(int num = 0; num != ptr.size(); num++){
Astruct *local;
local = ptr.at(num);
std::cout << " rank " << local->rank << "\n";
}
/*
// quick way to check whether certain address (eg 3rd element) exists in the std::vector
std::list<Astruct>::iterator it = ants.begin();
std::advance(it , 2);
for(int num = 0; num != ptr.size(); num++){
if(it == ptr.at(num)) std::cout << " exists in vector \n " ;
}
*/
// print memory in bytes for all variables
std::cout << " sizeof Astruct " << sizeof(Astruct) << "\n";
std::cout << " sizeof ants " << sizeof(ants) << "\n";
std::cout << " sizeof ptr " << sizeof(ptr) << "\n";
}
What's the way to access an address of a particular element from the list?
Is it efficient method to add elements to list? (in first for loop)
What is the quickest way to check whether certain address exists in the vector? (shown in comment block)
How to determine the memory size in bytes for different variables here? (end of the code)
Thanks.
What's the way to access an address of a particular element from the list?
address=&(*iterator);
Is it efficient method to add elements to list? (in first for loop)
the first loop does not use the list at all! (Ah, OK, after edition it does)
all the addresses which are stored in the vector refer to a local variable which disappears after each iteration; this is undefined behaviour (very probably, but nothing is certain, all these addresses are the same)
What is the quickest way to check whether certain address exists in the vector? (shown in comment block)
usualy std::find() from <algorithm> is suitable.
How to determine the memory size in bytes for different variables here? (end of the code)
std::cout << " sizeof Astruct " << sizeof(Astruct) << "\n"; is OK
std::cout << " sizeof ants " << size(ants)*sizeof(Astruct) << "\n"; is an approximation since we don't know the overhead of the list and its nodes
std::cout << " sizeof ptr " << size(ptr)*sizeof(Astruct *) << "\n"; is an approximation since we don't know the overhead of the vector
Take the following simple program:
struct Foo
{
int x;
int y;
int z;
string s;
};
int main()
{
Foo f1 = { 42,21,11, "Hello world" };
std::map<int, Foo> foomap;
foomap[400] = f1;
Foo* ptr = &foomap[400]; // cache a pointer to the element we just inserted.
cout << ptr->x << " " << ptr->y << " " << ptr->z << " " << ptr->s << std::endl;
// fill the map up with a bunch of other random items at random indices
for (int x = 0; x < 10000; x++)
{
int i = rand();
Foo f = { rand(), rand(), rand(), "Another string" };
if (foomap.find(i) == foomap.end())
{
foomap[i] = f;
}
}
Foo* ptr2 = &foomap[400];
cout << "f1 insert location has " << ((ptr == ptr2) ? "not changed" : "changed") << std::endl;
cout << ptr->x << " " << ptr->y << " " << ptr->z << " " << ptr->s << std::endl;
return 0;
}
So the program above caches a pointer to an item in the map. Then adds a whole lot more items into the map, and then validates if the first inserted item has changed location.
I was somewhat surprised when I ran it. The cached pointer stays intact:
42 21 11 Hello world
f1 insert location has not changed
42 21 11 Hello world
I would have assumed that as the map grows with respect to the number of items in it, the implementation might move items around - just like std::vector absolutely does.
So my question is this: Are items inserted into a map guaranteed to be at the same address as long as it's not removed from the map or replaced? Or is this implementation specific?
Yes, insertion / emplacement operations on map never invalidate iterators or references to existing items.
26.2.6 Associative containers [associative.reqmts]
9 The insert and emplace members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements.
I have two questions with respect to vectors.
Let us say I have a multi-dimensional vector as follows :-
vector< vector<int> > A;
Then A[0], A[1], etc are vectors. How are the vectors stored in A? I
mean what information about the vectors A[0] and A[1] is stored in A?
And does memory re-allocation of the individual vectors such as A[2]
cause re-allocation of A as well?
Second, I tried to see how the addresses of a vector change with re-allocation. I used the following code:-
Code:
vector<int> A;
int* x ;
int* y ;
vector<int>* ad;
vector<int>* bd;
for(int i = 0 ; i < 10000; i++){
A.push_back(i);
if(i == 2){
y = &A[0];
ad = &A;
}
x = &A[0];
bd = &A;
}
I found that, the address for A does not change even though the address for A[0] changes. This is to be expected since vectors work in the background by making use of new and delete. But my question is how much information (or which information) about the vector is stored in the address &A (considering the address of &A does not change ). This is the question I have with respect to the first question as well.
I am trying to better understand how vectors work by default.
how much information (or which information) about the vector is stored in the address &A
You are correct in assuming that the data for the vector is stored separately from the vector object itself - typically, in dynamic memory.
The three things the vector object itself needs to know are
The location of the vector's data - we need this to perform the [] operator,
The size currently allocated - we need this to know when to grow the array, and
The number of elements actually placed into the vector - we need this to know where to push_back, and what to return from size().
Different implementations are possible, storing as little as a single pointer in the vector object itself. However, a typical implementation stores a pointer to the beginning of the allocated block, a pointer to the end of the active part of the allocated block, and a pointer to the end of the allocated block.
Regarding the vector's address: The address of A does not change, not because A is a vector, but because no variable's address changes while the function where you define it (or rather, the specific call of your function) is executing. I think you may be confusing A's address (ad, bd in your example) with the address of what A uses to store the elements of the vector (x and y, essentially, in your example). Vectors allocate, de-allocate or re-allocate storage.
Note that A[0] is not a variable that you defined. It is the result of the invocation of A.operator[]; so its location can change.
Regarding what's actually stored at &A: That is kind of complicated. You will need to look at the header file vector within your C++ installation. Or perhaps it would be better to have a look at the webpage for std::vector at cppreference.com. Note there's a lot of templates, and some subclassing, and some explicit template specializations, so like I said - complicated. You might want reconsider whether you really want to look under the hood just to understand how this container works as a general rule, or whether the class' public methods and sizeof() figure are sufficient for now.
I am a beginner in c++ and STL, so I just test your problem with some simple codes;
first, i have these codes:
std::vector<int> tmp;
std::cout << sizeof(tmp) << " " << tmp.size() << " " << tmp.capacity << std::endl;
the output is:
12 0 0
then, we insert some values into the vector
for(int i = 0; i != 10; ++i) tmp.push_back(i);
std::cout << sizeof(tmp) << " " << tmp.size() << " " << tmp.capacity << std::endl;
the output is
12 10 16
then, we can draw a conclusion that the vector just keep a pointer, so the sizeof() result didn't changed.
So, the answer of your question is , the child vector's push_back will not result in the reallocation of the parent vector(i don't know how to express the role of these two vectors).
There are some simple codes:
std::vector<int> v1(10);
std::vector<int> v2(10);
int i;
for(i = 0; i != 10; ++i)
v1[i] = i;
for(i = 0; i != 10; ++i)
v2[i] = i;
vv.push_back(v1);
vv.push_back(v2);
std::cout << "v1 capacity: " << v1.capacity() << " v1 size: " << v1.size() << std::endl;
std::cout << "v2 capacity: " << v2.capacity() << " v2 size: " << v2.size() << std::endl;
std::cout << "vv capacity: " << vv.capacity() << " vv size: " << vv.size() << std::endl;
for(i = 10; i != 20; ++i)
v1.push_back(i);
for(i = 10; i != 20; ++i)
v2.push_back(i);
std::cout << "v1 capacity: " << v1.capacity() << " v1 size: " << v1.size() << std::endl;
std::cout << "v2 capacity: " << v2.capacity() << " v2 size: " << v2.size() << std::endl;
std::cout << "vv capacity: " << vv.capacity() << " vv size: " << vv.size() << std::endl;
output:
v1 capacity: 10 v1 size: 10
v2 capacity: 10 v2 size: 10
vv capacity: 2 vv size: 2
v1 capacity: 20 v1 size: 20
v2 capacity: 20 v2 size: 20
vv capacity: 2 vv size: 2
can someone please explain to me in detail why the following code for vectorY will do the assignment but the size of VecY is zero? Also, the begin and end iterators are stuck at the first node. It seems that reserve only works with push back and that you need to construct the vector with the size if you want the iterators for the vectors and the size to work as expected. I am assuming that push_back is doing some type of allocation that the straight assignment is not in this case? I am looking for details explaining this so I can make sure I understand what is happening with a reserve and push_back versus constructing with a size element and then doing assignment as in VecX example.
#include <iostream>
#include <vector>
int main ( int argc, char *argv[])
{
std::vector<int> vecX(2);
vecX[0] = 1;
vecX[1] = 2;
std::cout << " VecX0 Item: " << vecX[0] << std::endl;
std::cout << " VecX1 Item: " << vecX[1] << std::endl;
std::cout << " VectorX Size: " << vecX.size() << std::endl;
std::vector<int> vecY;
vecY.reserve(2);
vecY[0] = 1;
vecY[1] = 2;
std::cout << " VecY0 Item: " << vecY[0] << std::endl;
std::cout << " VecY1 Item: " << vecY[1] << std::endl;
std::cout << " VectorY Size: " << vecY.size() << std::endl;
}
Output
VecX0 Item: 1
VecX1 Item: 2
VectorX Size: 2
VecY0 Item: 1
VecY1 Item: 2
VectorY Size: 0
std::vector<int> vecY;
vecY.reserve(2);
vecY[0] = 1;
vecY[1] = 2;
This code is wrong and evokes Undefined Behavior1. When you reserve a vector, you set the capacity, not the size.
You need to either push_back, or construct the vector as you did in example 1.
"Undefined Behavior" : This invokes Undefined Behavior because of the out-of-range call to operator[] If you call vector::operator[n] where n > vec.size(), the behavior is Undefined.
If you don't want use push_back nor construct, consider using the resize method
i'm trying to store some elements that is going to change every time, but i don't know which
way is better and why. I'm thinking about two ways, 1) declaring array of int and loop or
use vector's.
Which way is better and why?
Does declaring array of int have any future memore problems as leak?
the code down below show the two ways i'm talking about:
1)
#include <iostream>
#include <vector>
int main()
{
int x[5];
x[0] = 10;
x[1] = 20;
x[2] = 30;
x[3] = 40;
x[4] = 50;
for(unsigned int i = 0;i<=sizeof(x[5]); i++)
{
std:: cout << "x[" << i << "] = "<< x[i] << std::endl;
}
system("pause");
return 0;
}
2)
#include <iostream>
#include <vector>
int main()
{
std::vector<int> x;
x.push_back(10);
x.push_back(20);
x.push_back(30);
x.push_back(40);
x.push_back(50);
for(unsigned int i = 0;i<=x.size()-1; i++)
{
std:: cout << "x[" << i << "] = "<< x[i] << std::endl;
}
system("pause");
return 0;
}
If this is all you have to do, and your array will always have a size that is known at compile time, then you do not need std::vector.
On the other hand, in C++11 you could use std::array instead of a plain C array (std::array is a zero-overhead, safer and more functional wrapper over a C array):
#include <iostream>
#include <array>
int main()
{
std::array<int, 5> x = { 10, 20, 30, 40, 50 };
for (unsigned int i = 0; i < x.size(); i++)
// ^^^^^^^^
{
std:: cout << "x[" << i << "] = "<< x[i] << std::endl;
}
}
Here is a live example. Notice, that std::array offers a size() member function which you may want to use instead of the sizeof operator.
Moreover, since std::array is a standard sequence container, you could iterate through its element this way:
std::size_t i = 0;
for (auto e : x)
{
std:: cout << "x[" << i++ << "] = "<< e << std::endl;
}
Here is a live example.
If the size is known at compile time, use std::array. If not, use std::vector. In either case, use iterators to look at the elements:
typedef std::array<int> my_container_type;
typedef my_container::iterator iterator;
my_container_type my_container = { whatever };
for (iterator it = my_container.begin(); it != my_container.end(); ++it)
std::cout << "x[" << (it - my_container.begin()) << "] = " << *it << '\n';
By using iterators you greatly reduce the risk of accidentally using a loop limit like sizeof(x[5]), which is nonsense.
Neither is "better". They both address entirely different use cases.
If you know the array size at compile time and are 100% sure it will never change, sure, use a plain old array. It has less overhead, and the compiler can even aid you with static analysis by spotting any attempts to read outside the boundaries.
On the other hand, if you are unsure of the array's side (i.e. you will be reading input from a file or the user), then use the std::vector. It can grow to any size to meet your needs.