Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why don't I need to check if references are invalid/null?

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?

like image 738
jbu Avatar asked Mar 26 '10 16:03

jbu


People also ask

Can a reference ever be null?

“References cannot be null, whereas pointers can; every reference refers to some object, although it may or may not be valid.”

What is there is no null reference?

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.

Can we store null reference to reference variable yes?

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.

Can references refer to invalid location in C ++?

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.


2 Answers

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 
like image 145
Brian R. Bondy Avatar answered Oct 02 '22 13:10

Brian R. Bondy


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.

like image 45
Edward Strange Avatar answered Oct 02 '22 13:10

Edward Strange