Did I understand references and pointers correctly?

I have been reading about references and pointers everywhere but I still have some questions.

From what I got, references are marked by & and pointers with * and they are the same. Pointers can be null and references cant be null unless they are const. And references are like "out" values. (like to reference to another variable so it can be modified through the reference )

But what would be the point of having for example a const null string? What can I do with a null string if it cant be modified on runtime?
When do I really have to use pointers? When I dont use pointers it is recommended to always use references? Is there any case I shouldn't use references?
I don't think you understand them at all...

I wouldn't say that I'm 100% proficient, but this is how I understand them:

As parameters in a function header

Example:
1
2
3
4
5
6
7
void foo(int *a, int& b); //the spaces don't matter

int main()
{
    int x, y;
    foo(&x, y);
}

Inside foo, a is a pointer to the variable x in main, and b is a reference to the actual y inside main. This means that modifying b also modifies y. To modify x, you need to dereference a first. (EG *a = 10; changes x in main to be 10.)

Outside of function headers

Example:
1
2
3
4
int x;
int *y;
y = &x;
cout << *y;

The second line is declaring y as a pointer to an int. The third line assigns the address of x to y (used outside of function headers, the ampersand means the address of the variable it precedes). Yes, pointer variables hold memory addresses, not whatever type it is a pointer of. Line 4 is dereferencing a pointer (used outside of declarations, the asterisk is a dereference operator) and outputting the value contained in the address that y points at.

EDIT:

And here's an example that I didn't understand until recently:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void foo(int *a)
{
    int b = 10;
    a = &b;
    cout << *a << endl;
}

void bar(int &*a)
{
    int b = 5;
    a = &b;
    cout << *a << endl;
}

int main()
{
    int c = 1;
    int *d = &c
    cout << *d << endl;
    foo(d);
    cout << *d << endl;
    bar(d);
    cout << *d << endl;
    return 0;
}
1
10
1
5
5

In main, d contains the address of variable c, which contains the value 1. So when you dereference d and output it, you get 1. Then d is passed as a parameter to the function foo.

In foo, a is a copy of d. Changing a to point to b in the function means that dereferencing a gives us the value of b (which is 10). This does not change d inside main. Dereferencing d still gives us 1.

In bar, a is a reference to the pointer d. Changing a to point to b means that d is also changed to point to b. Dereferencing a or d both gives us 5.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>

int r2x(int x)
{
  return x *= 2; // return x * 2
}

void r2xr(int &x)
{
  x *= 2; // multiply x by 2
}

void r2xp(int *x)
{
  *x *= 2; // multiply the value pointed to by x by 2
}

int main()
{
  int i = 9;    // integer, initialized to 9
  int x = 0;    // integer, initialized to 0
  int *ip = &i; // pointer to int, set to address of i

  x = r2x(i);   // i = 9, x = 18
  r2xr(x);      // i = 9, x = 36
  r2xp(ip);     // i = 18, x = 36

  return 0;
}
See also:
http://www.LB-Stuff.com/alias
http://www.LB-Stuff.com/pointers
Pointers and references should be treated very differently.
Last edited on
I've been reading and reading but I don't see differences (I'm probably not understanding well...) the * (pointer) operator stores the memory address of the variable, right? And to get the pointer value I need to de-reference it (aka, putting the * before the name). And Address-of (&) returns the memory address of the variable.

1
2
3
4
5
6
7
8
9
int number = 5; // Creating a number variable with value "5".  
cout << number << endl; // Here I print the number variable. (5)
cout << &number << endl; // Here I print the memory address of the number variable. (It's 0x28fde8)
int *numberPointer = &number; // At here i'm creating an int pointer to the number address (numberPointer = (0x28fde8))
cout <<  numberPointer << endl; // Here i'm printing the memory address of the numberPointer which is the same as number (It's 0x28fde8)
cout << *numberPointer << endl; // Here i'm dereferencing it and this should return the same value as number. (It's 5.) 
*numberPointer = 3; // Again dereferencing it so I can change the numberPointer to 3.
cout << *numberPointer << endl; // Printing again the numberPointer value to see if it changed. (It's 3.)
cout <<  number << endl; // Since both number and numberPointer share the same address number has changed to 3 too. 


I do know that if I want to reference some variable (like an _out, sorry, I call it like this) I do this:

1
2
3
4
5
6
7
8
9
10
11
12
void a(int &b) { // I have a &b, which is a reference to the variable I pass as a parameter whenever I call a().
    cout << b << endl; // Print B. Should be 1.
    cout << &b << endl; // Print B address. Now it's 0x28fe34. Same as c since b is a reference to c.
    b = 3; // Change B to 3.
    cout << b << endl; // Print B. Should be 3.
}

int c = 1; // Variable named c as integer with the value 1.
cout << c << endl; // Print C. Should be 1.
cout << &c << endl; // Print the address. It's 0x28fe34.
a(c); // We call a with c as a parameter.
cout << c << endl; // We print c and see it changed to 3 since in a, &b is a reference to a and they both share same address. 


But then why if I do this: &b doesn't return the same address as the pointer address?

1
2
3
4
5
6
7
8
9
10
11
12
13
void a(int *b) { // i have a b variable pointing to an int.
    cout << *b << endl; // Dereference B and prints it's value. It should be 1.
    cout << &b << endl; // Print B address. For some reason it's 0x28fe10 and not 0x28fe34.
    cout << b << endl; // Print to where B points at. It's 0x28fe34.
    *b = 3; // Change B to 3.
    cout << b << endl; // Print B. Should be 3.
}

int c = 1; // Make a variable called c with value as 1.
cout << c << endl; // Print c value. It should be 1.
cout << &c << endl; // Print c address. It's 0x28fe34.
a(&c); // Call a() with c address.
cout << c << endl; // Print c value. It should be 3 now. 


And for last, when do I really have to use * and &? That confuses me a lot.

Thanks for the help.
You are confusing the address-of operator & with the reference type &. They use the same symbol but are drastically different things.

Read these to understand some differences between pointers and references:
http://stackoverflow.com/a/57492/1959975
http://stackoverflow.com/a/7058373/1959975

The difference is less in semantics and more in the implications - the way they are used and treated is dramatically different, even though under the hood they are the same thing.
http://www.LB-Stuff.com/alias

Pointers are not very useful in C++ anymore. In my opinion you should avoid them 99% of the time.
http://www.LB-Stuff.com/pointers

See also JLBorges' post below:
Last edited on
> I've been reading and reading but I don't see differences

Perhaps, this may help: http://www.cplusplus.com/forum/general/139756/#msg739214
So this is also why it's recommended to avoid using new? Because it returns a pointer and people tries to avoid them?
So this is also why it's recommended to avoid using new?

Not quite. When you use new, you have to use delete too and do it correctly. That is far from trivial.

I'll show you a small program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <string>
#include <iostream>
#include <cstdlib>

void foo( std::string bar ) {
  if ( (rand() % 100) < 42 ) throw 7;
  std::cout << bar << '\n';
}

int main() {
  std::string text = "Brown fox jumps over the lazy dog.";
  foo( text );
  return 0;
}

I do presume that most standard library implementations use new (and delete and pointers) within that program, do it correctly, and most importantly I don't have to worry about it.


A pointer is a variable. Variable requires memory, when the program runs. A pointer has a number in that memory.

A reference is just a name alias within the source code. It does not consume memory in running program.
Remember: variables do not consume memory; objects do.
Well each time I read something about new lot of people jump with "I'd avoid using new" or whatever.

(Let me see if I got it now, been having a hard time with this somehow...)

References aren't objects, they're only name alias and they don't consume memory.

Pointers have a number value that points to an address, which can be changed (and set to null) and they consume memory and they have their own region in memory.
The way to understand it is that references are not objects, but pointers are. A pointer is an object which points to another object. A reference is just an alias like any other variable. You can have a reference to a pointer but not a pointer to a reference.
http://www.LB-Stuff.com/alias
Last edited on
I see. How does & work in this case?

1
2
3
const int &MyClass::MyFunction() const {
// ...
}
The function MyClass::MyFunction returns a reference to an integer, and that integer cannot be modified through the reference because of the const keyword. However, if the integer is changed by some other means (e.g. class internals), you would see that change through the reference. It is effectively a read-only view of a possibly mutable integer.
Last edited on
Topic archived. No new replies allowed.