1

The following code is to verify if I have a pointer member in a class, without making an overloaded assignment operator. When I make two instances equal,it will just make the pointers point to the same thing instead of copying the data. However, I got an error trying to compile before I could verify. It appears to me that it implies a pointer member in class has to be pointed to a heap-allocated data. Is it right?

The error is: initializing pointer member 'a' with the stack address of parameter 'aa' [-Werror,-Wdangling-field]

Second question is when do we need an overloaded "="operator? I guess would be when we have a pointer member in the class and we want whatever the pointer points to to be copied again instead of just making two pointer from the two classes point to same thing. Could somebody tell me this is correct. Thanks!

class ClassA {    
  int* a;  
  int* b;  

  ClassA():a(NULL),b(NULL){};

  ClassA(int aa,int bb):a(&aa),b(&bb){};                                                                                                                                                                                     
};

int main(){ 

  ClassA test;
  ClassA subject(5,6);

  test = subject;
}
Pavel
  • 7,436
  • 2
  • 29
  • 42
Jiao
  • 53
  • 5
  • 4
    `aa` is a local variable on the stack. You don't want to save its address. Have the `ClassA` constructor take `int*` (x2) instead of `int`. And no, there's no rule that class members that are pointers must point to heap memory. – dlf Jun 12 '14 at 19:43
  • 1
    Why do you need `int* a;` and `int* b;` there, instead of simply `int a;` and `int b;`?!? I'd suspect you have a XY problem here! – πάντα ῥεῖ Jun 12 '14 at 19:45
  • Yes, you need to overload `operator=` when the default shallow copying behaviour will do the wrong thing, or when you want to be able to assign a different type to your class without going through a constructor. – chris Jun 12 '14 at 19:46
  • 1
    For the second part of your question, see [this famous question](http://stackoverflow.com/q/4172722/3549027) – dlf Jun 12 '14 at 19:47
  • @chris Then certainly this one is relevant: http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three – πάντα ῥεῖ Jun 12 '14 at 19:47

2 Answers2

5

Explanation

No, there's nothing saying that he address contained in a pointer must be the location of an object with dynamic storage duration, but please be careful when initializing them with addresses of variables on the stack (having automatic storage duration).


As your compiler tells you; you are currently assigning the address of two temporaries to the pointers inside your class. This means that after the constructor is finished, and aa and bb are no longer alive, but you can still potentially refer to them through this->a, and this->b.

If you try to use *(this->a) and *(this->b) when their pointed-to-object in no longer available you are invoking undefined behavior, meaning that your application will most likely crash since you are trying to access memory which is no longer valid to use.


When do I need operator=?

This is an often asked question on stackoverflow, and I'd recommend you to read through the below questions/answers:

Community
  • 1
  • 1
Filip Roséen - refp
  • 62,493
  • 20
  • 150
  • 196
1

this line doesn't look good:

ClassA (int aa, int bb) : a(&aa), b(&bb) {}; 

the parameters are plain integers, so they come in by-value, it means their copies exist on the stack as long as the constructor scope goes. then they're gone. your pointers now point to unalocated memory, so dereferencing would lead to a segfault.

as for your second question, please read this thread that gives a beautiful explanation for the assignment operator.

Community
  • 1
  • 1
Pavel
  • 7,436
  • 2
  • 29
  • 42
  • Didnt occur to me that parameters will only stays in the constructor scope just like function parameters. Thanks! Now I get it! – Jiao Jun 12 '14 at 20:07