Hey all, teaching myself CPP through a few books (and a little bit of CS in general through CS50) and hit a road block.
I understand what pointers are, and understand they’re a big part of programming. My question is why?
What do you use pointers for? Why is forwarding to a new memory address preferable to just changing the variable/replacing what’s already at the memory address or at a new one? Is it because new data could exceed the size of that address already allocated?
Thanks in advance!
Some things are too big to store on the stack and you need them in the heap. Those two words may be gibberish right now but it gives you a new thing to learn.
deleted by creator
My advice is to learn pure C and make a few small programs with it. You’ll see very soon why pointers are necessary.
deleted by creator
There are things you’ll want to do that will eventually require pointers. For example, as soon as you want a type that contains a reference that could be rebound, you need a pointer.
If you want to implement polymorphism you’ll need pointers. If you instead want type erasure, you’ll need pointers to implement your type erasure container.
Sure it’s possible to implement a lot without pointers, but the code will be harder to write and will probably be slower.
Ton of thanks for all the replies and examples. Some of it is over my head at the moment but most of it has shed some light none of the self-teach material has gotten into, I appreciate that.
Letting this all sink then hitting the books again!
A really simple way you can look at pointers is like this: every time you want to see my house, I could rebuild a complete copy of my house for you, but wouldn’t it be easier if I could give you a note with my house’s address so you could just visit it there?
In the second example, the note is an analogy for a pointer.
Pointers also allow you to do fun and dangerous things like casting between types!
For example, if you’re implementing your own memory allocator, at the base level your allocator only really cares about how many bytes are being requested (along with alignment, offset, other things) so you’d probably just implement it to return a char*, u8*, or void* pointing to the blob of memory you allocated with new, malloc, or whatever scheme you’ve cooked up. The calling code or higher level allocator code could then cast it to the actual type
Something else that people haven’t touched on yet is dynamic memory allocation. Whenever you create a new object you’ll need a reference to it. That reference is a pointer.
Hi OP, pointers are very powerful. You’ve already seen some responses to your question about why/when to use it, but there’s another cool trick I like to do with pointers. Namely, data hiding with opaque pointers (an application of type erasure). Especially in library code where I don’t want to introduce too many includes in the consuming application, I will hide data and implementation using the pimpl idiom. Another great use case for pointers.
You need pointers to implement low-level stuff or for example containers. Sometimes you really just need the memory address itself e.g. for MMIO. That said, much of the stuff is implemented for you by the standard library and you do not usually need to directly use the pointers. That might change in embedded space.
Shared ownedship is another part where (reference-counted) pointers are useful.
std::shared_ptr
is this. I would generally say that shared ownedship in itself is much harder to reason than non-shared, but there are situations where you really want shared ownership.Pointers in general shouldn’t be your go-to tool. They are easy to mess up with, and memory errors are annoying to debug. And in my experience people who are overconfident in their use are the ones writing the worst security holes and incomprehensible interfaces. (Though those overconfident people with their BS keep me in business, so there’s that.)
All that said, I wouldn’t even teach pointers and raw memory stuff in the C++ intro course if I didn’t know it comes up so often in job interviews.
One thing to remember is that arrays are just pointers under the hood. Even if you don’t use them directly, or are always using smart pointers like
std::shared_ptr<T>
, they’re still there.For example, accessing the following array:
int foo[3] = {1, 2, 3}; // foo is identical to int*, except the type contains a size foo[1] == 2; *(foo + 1) == 2;
Realistically in modern C++ you could likely avoid raw pointers entirely. C++ references cover a ton of the pointer use cases. I’d say the main goal is to prevent data from being copied around needlessly, since that takes more time and memory bandwidth.
It doesn’t “forward to”, it is a way to say “ehi, this data X is located at …”
Imagine having a big large data structure that takes up a lot of space. You have to pass it a function to perform some operations, but if pointers didn’t exist you would have to clone those data - which is expensive memory wise and probably time wise to. So instead of wasting either space or time, you simply pass a memory address to that data and using it you can access the original data.
Obviously if you have primitive data structures, such as integers, or that you know that aren’t expensive to clone, you can simply pass by value and call it a day (somewhere on learncpp theee is a very nice explanation of all of this)
I’ll be searching learnccp for your reference. Thanks! Also huge thanks to everyone who keeps pouring the knowledge in! You guys rock!
I’ll be searching learnccp for your reference
I have never used the learncpp site, IMHO you should use https://en.cppreference.com/w/ which is written by a guy that is really invested in the language.
I haven’t used pointers for a long time, I only use smart pointers nowadays. As for your question: just changing the variable/replacing what’s already at the memory address, the answer is also “sometimes you can’t” because some objects cannot be cloned or duplicated like sockets or threads.
IMHO pointers (raw or smart) are barely necessary in modern C++. In many cases, references and standard library classes like
std::vector
do whatever pointers do, but without the manual memory management. I use pointers for interacting with C libraries and in HIP/CUDA. In “pure” C++ the only thing that comes to mind is storing objects of different derived classes in a vector.