Reading http://www.cprogramming.com/tutorial/references.html, it says:
In general, references should always be valid because you must always initialize a reference. This means that barring some bizarre circumstances (see below), you can be certain that using a reference is just like using a plain old non-reference variable. You don't need to check to make sure that a reference isn't pointing to NULL, and you won't get bitten by an uninitialized reference that you forgot to allocate memory for.
My question is how do I know that the object's memory hasn't been freed/deleted AFTER you've initialized the reference.
What it comes down to is that I can't take this advice on faith and I need a better explanation.
Can anyone shed some light?
“References cannot be null, whereas pointers can; every reference refers to some object, although it may or may not be valid.”
Because a reference carries the semantic that it points to a valid memory address that never changes; i.e. that dereferencing it is safe/defined and so no NULL checks are required. References cannot be reassigned by design. You use a pointer when the var can be NULL and client code has to handle that case.
3. Reference variable can also store null value. By default, if no object is passed to a reference variable then it will store a null value.
In C++, Reference variables are safer than pointers because reference variables must be initialized and they cannot be changed to refer to something else once they are initialized. But there are exceptions where we can have invalid references.
You can't know if references are invalid:
There is no way to know if your reference is referencing valid memory except by taking care of how you use references. For example you don't want to use a reference with something created on the heap if you are unsure when the memory will be deleted.
You also can never know whether the pointer you are using is pointing to valid memory or not as well.
You can do NULL checks with both pointers and references but typically you would never do a NULL check with a reference because no one would ever write code like this:
int *p = 0; int &r = *p;//no one does this if(&r != 0)//and so no one does this kind of check { }
When to use a reference?
You probably want to use references in cases like this:
//I want the function fn to not make a copy of cat and to use // the same memory of the object that was passed in void fn(Cat &cat) { //Do something with cat } //...main... Cat c; fn(c);
Shooting yourself in the foot is hard with references:
It's much harder to shoot yourself in the foot with references than it is with pointers.
For example:
int *p; if(true) { int x; p = &x; } *p = 3;//runtime error
You can't do this sort of thing with references since a reference must be initialized with it's value. And you can only initialize it with values that are in your scope.
You can still shoot yourself in the foot with references, but you have to REALLY try to do it.
For example:
int *p = new int; *p = 3; int &r = *p; delete p; r = 3;//runtime error
You can't. You also can't with a pointer. Consider:
struct X { int * i; void foo() { *i++; } }; int main() { int *i = new int(5); X x = { i }; delete i; x.foo(); }
Now, what code could you put in X::foo() to make sure that the i pointer is still valid?
Answer is that there is no standard check. There are some tricks that might work on msvc in debug mode (checking for 0xfeeefeee or whatever), but there's nothing that will consistently work.
If you need some sort of object that makes sure the pointer does not point at freed memory you'll need something much smarter than a reference or standard pointer.
This is why you need to be pretty darn careful with ownership semantics and lifetime management when working with pointers and references.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With