2

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!

4
  • 1
    I don't know. Do you really need to use pointers? Can you not just use DatClass dc; instead of DatClass* dc;? That would get rid of both problems (how to get unique pointers and where to put delete). Commented Oct 24, 2012 at 13:34
  • 2
    It's not clear what you're trying to do -- the loop in Test() doesn't even look at the vector v, except to measure its length. Commented Oct 24, 2012 at 13:36
  • 1
    Your code is totaly wrong. I even cant understand from where start to critic this code. First you need to understand arguments referenced by value and by reference. Second - lifetime of local variables. Third - smart pointers for avoiding delete operator. Commented Oct 24, 2012 at 13:37
  • If my code wasn't wrong I wouldn't need to ask, thank you. And this code is obviously an example to understand the underlying mechanic. Commented Oct 24, 2012 at 13:40

6 Answers 6

3

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.

Sign up to request clarification or add additional context in comments.

6 Comments

+1 for mentioning that the memory is usually allocated on stack
Wouldn't that delete the member of OtherClass as well and throw a segmentation fault if I tried to access otherClass.dc->m later on?
@Shal: I don't understand what are you asking. Where do you want to access the class? Where do you assign otherClass.dc as the new class? Your comment is vague.
It is, I forgot to add the assignment it->dc = &dc;, because I was so focused on the addresses. Apologies.
@Shal: In this case, you need to delete the object when you are done with it, a good place will be in the destructor of OtherClass. You could also make dc of type DataClass instead of DataClass*, if it is possible - and avoid all of this.
|
2

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;
  }
}

Comments

1

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.

Comments

0

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/

Comments

0

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)

Comments

-1

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

1 Comment

Not sure why the negative on this answer. It's similar to Andrey's. Only objection I can think is OP seems to try (and fails) to assign a new DatClass to OtherClass (DatClass dc = DatClass(i); then it->dc = &dc), which this answer don't address (nor Andrey's)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.