Reputation: 57
I need to create object pointers in a loop, but I am struggling with creating unique pointers. Here's my code:
class DatClass{
public:
int m;
DatClass(int i):m(i){}
};
class OtherClass{
public:
DatClass* dc;
};
void Test(std::vector<OtherClass> v){
std::vector<OtherClass>::iterator it;
int i = 1;
for(it = v.begin(); it != v.end(); it++){
DatClass dc = DatClass(i);
std::cout << &dc << std::endl;
it->dc = &dc;
i++;
}
}
int main(){
std::vector<OtherClass> v;
v.push_back(OtherClass());
v.push_back(OtherClass());
v.push_back(OtherClass());
Test(v);
}
This does not give me unique pointers. The output reads:
0xbf94d72c
0xbf94d72c
0xbf94d72c
Do I need to use new in order to get unique pointers? If so, where would I put the corresponding delete? Thanks!
Upvotes: 2
Views: 2659
Reputation: 1239
I think you may be trying to assign a new DatClass to OtherClass, but instead you're assigning an auto (on the stack) DatClass, that is destroyed at each loop iteration, because it's an automatic object (and the compiler is reusing its address on the stack, that's why you always see the same address)
I'd rather replace this:
for(it = v.begin(); it != v.end(); it++){
DatClass dc = DatClass(i); // auto object destroyed and address reused
std::cout << &dc << std::endl;
it->dc = &dc;
with this:
for(it = v.begin(); it != v.end(); it++){
DatClass *dc = new DatClass(i); // new object on heap
std::cout << dc << std::endl;
it->dc = dc;
so now you are creating new DatClass objects to assign to OtherClass objects.
(besides, you should also somewhere delete
those new DatClass objects, to avoid resource leaks)
Upvotes: 0
Reputation: 2181
Short you are trying to do this dynamically. This means nu are not on stack you are on heap. So more memory will be allocated only if you need or use it not at program start up.
So int a = 5; <<< stack
and new int* b = 55
(when finished using it you MUST free the memory with delete b;
or bad segmentation fault errors you will get later.);
`cout<< &b;` prints the value stored at the pointer ` 55`
`cout<< *b` prints the pointers value in memory `#1234` i think this is called offset
i recomand you for this kind of basic questions: http://www.cplusplus.com/doc/tutorial/
Upvotes: 0
Reputation: 74018
You print the address of dc
. dc
is on the stack at the same location every time. That's why you get the identical address every time.
You could change your loop to:
for (auto it = v.begin(); it != v.end(); ++it){
OtherClass *oc = &(*it);
std::cout << oc << std::endl;
}
which gives you the addresses of all objects in v
Upvotes: -1
Reputation: 8594
DatClass dc = DatClass(i);
creates an instance of the class on the stack. Its address remains the same in the loop, that's why the output is the same.
You may want to do following:
void Test(const std::vector<OtherClass>& v){
std::vector<OtherClass>::iterator it;
for(it = v.begin(); it != v.end(); it++){
const DatClass& dc = *it;
std::cout << &dc << std::endl;
}
}
Upvotes: 2
Reputation: 437336
Each iteration of the loop inside Test
creates a new DatClass
instance on the stack and prints its address. Before the next iteration, this object's lifetime ends and this enables the compiler to reuse the same memory on the next iteration.
This is why you always see the same address (of course it's only possible because the standard specifically allows the compiler to do that).
If you want to see different addresses for the objects then you should either allocate all of them in function scope outside the loop (in which case they will reside on the stack but at different addresses) or else allocate them on the heap.
Of course it should be obvious that it doesn't make any difference what the vector
itself contains, since this affects only the number of iterations the loop does. If you change the code to print the addresses of the objects actually inside the vector
you will also see different addresses.
Upvotes: 1
Reputation: 178421
Yes, you should use new
to get unique addresses.
The delete
should be when the loop is done - otherwise (delete is inside the same loop) - the OS could give you the same address again.
(Or to be exact - when you are done with the object allocated in this address)
What's going on in your code is that you use an automatically allocated memory. This memory is usually allocated on the stack - and in each iteration - the same memory is reused for the variable - thus it gives you the same address.
Upvotes: 3