1

Alright so I've been getting deeply into C++ as of late and I'm getting everything down. Pointers are finally starting to make sense as far as when I should use them, how to implement them correctly, etc.

However, there was one little question about the fundamental use of pointers that I still had that needed answered. I'll jump right to the code:

With the following class A and function foo(A* bar)...

class A
{}

void foo(A* bar)
{}

... what's the difference between the following calls to foo?

A* a;
A b;

foo(a);
foo(&b);

They both compile fine, and as far as I can remember I haven't had any issues with them.

I think that A b; is instantiated right there, whereas A* a; needs to be created with new (since it hasn't actually created the object, it's just held a 4-byte long reference to a potential A object).

I could, if I am thinking about this correctly, do a = b; (EDIT make that a = &b) and then successfully pass a to foo. But, if I don't do a = &b and foo tries to read the (non-existent) object pointed to by a, it will causes runtime errors.

Also, if the above is correct, then it's assumed I can successfully call foo(&b); just fine.

Am I correct?

Thanks!

Matt
  • 22,721
  • 17
  • 71
  • 112
Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145

4 Answers4

5

Yes, Your understanding is correct.

 foo(&b);

passes address of an already existing object of type A as an parameter to function foo().

foo(a);

passes a pointer to the type A as function parameter. To be able to do anything meaningful it must point to a valid A object.It can be done in two ways:

Allocating object on stack:
Create an object of the type A on stack(local storage) & make the pointer a point to this object:

A* a;
A b;

a = &b;

Dynamic Memory allocation:

   A *a = new A;

Though, Once you do a dynamic memory allocation you will have to remember to free the alloated memory explicitly after use, or you will have a memory leak:

delete a;

Note that it is always better to avoid dynamic allocations as far as possible, and if you must do so, use Smart pointers instead of raw pointers.

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
4

You can't do a = b.

It would have to be a = &b, to set a to the address of b.

You are also correct about the memory management: b is allocated on the stack, while a allocates space only for a pointer and leaves creating the actual object to you.

foo(&b) will work file, where the behavior of foo(a) would be undefined before you initialize *a (such as via a = new A()).

Borealid
  • 95,191
  • 9
  • 106
  • 122
3

In C++, pointers are first-class objects. A pointer isn't just an invisible reference that needs an associated object to have an identity. That's how Java/C# references work (or most other languages, really), but a pointer is an object in itself.

So A* a declares a pointer. It doesn't point to anything, and it doesn't have to point to anything. And if/when it points to something, it doesn't need to own that something.

So you don't need to do a = new A(). You can do a = &b as well (to have a contain the address of the object b. Or it can point to any other object of type A as well. A pointer is just an object that stores an address. It's key to your understanding that you throw away the notion that it "has an object" which "needs to be created".

It is an object, which contains an address (or it contains the special value null), and if it contains an address, there may or may not be an object of type A at that address.

jalf
  • 243,077
  • 51
  • 345
  • 550
0

You are mostly correct. You should not assume that pointers are 4 bytes (for example, it might be 8 on amd64 systems). Also, your assignment should be a = &b; (note the addition of the address operator). Other than that, it sounds pretty reasonable.

FatalError
  • 52,695
  • 14
  • 99
  • 116