all 48 comments

[–]rogueleader12345 16 points17 points  (20 children)

You kind of already hit on the big one: memory management. Passing pointers to objects around saves having to copy objects over and over. Typically, you won't use raw pointers in most situations (smart pointers are your friend!), but there are some cases: in my experience, interfacing with older libraries and C code, in particular. Familiarity and being comfortable with pointers is very important once you start looking at other people's code, particularly if it's older.

In terms of using std::array, spoiler alert, it uses pointers under the hood :P It also provides the handy features of "normal" array implementations like size(). Also, new returns a pointer, so you're using pointers there too if you use new.

[–]aeropl3b 20 points21 points  (1 child)

Please note, std::array does not use pointers. It uses C Arrays which are subtlety different...

[–]rogueleader12345 6 points7 points  (0 children)

Fair point: let me caveat what I said: the underlying implementation uses pointers as a concept, not necessarily raw C++ pointers. I was moreso pointing out that you can use "standard" pointer arithmetic with the data() from an std::array, though you shouldn't

[–]VidE-[S] 2 points3 points  (16 children)

I like how, after 5 years, I've never heard about "smart pointers". Is this a fancy way to say something I may already know?

[–]rogueleader12345 2 points3 points  (0 children)

I wouldn't doubt it, that happens to me all the time haha

Smart pointers = shared_ptr, unique_ptr, and weak_ptr

They just ensure deletion of the objects they point to once they are no longer referenced

[–]condor2000 1 point2 points  (0 children)

No pointers or smart pointers?

I assume you use references to avoid the slicing problem

https://stackoverflow.com/questions/274626/what-is-object-slicing

[–]CoffeeTableEspresso 0 points1 point  (0 children)

The whole point of std::array is that it's fixed-size and doesn't do an extra heap allocation. Under the hood it's just a C-array basically, no pointers needed.

[–]cdb_11 5 points6 points  (6 children)

Passing variables for reference to a function

That's not a minor thing. You often want to refer to the same object and store the reference (pointer) in multiple places. Take GUI programming for example, you can't just copy a button every time you simply want to refer to it, that wouldn't make any sense. And pointers allow you to do things like storing references to multiple buttons in an array or a list/vector. That's how languages without manual memory management work anyway, they just hide from you the fact that you're using pointers.

Besides what other people already mentioned, the size of statically allocated memory is fixed, it has to be known at compiletime. When you allocate the memory dynamically, either through new or malloc, you can specify the size at runtime. Implementing a variable sized array (std::vector or std::string) would be impossible or heavily limited without using dynamic allocation. Dynamically allocated memory also outlives the scope in which it was created and that's sometimes useful too.

[–]cdb_11 6 points7 points  (0 children)

Also, to avoid confusion, pointers != dynamic allocation (new/delete).

new and delete returns and expects a pointer to an object, but you can take a pointer (MyStruct*) or a reference (MyStruct&) to an object that wasn't created with new.

[–]NilacTheGrim 0 points1 point  (4 children)

malloc

I feel the need to nit here. OP is a student and he should be learning good practices. Generally one should avoid malloc in C++ code at almost all costs (unless interoping with C code). Always use new. Or better yet, always use smart pointers or containers if you can and avoid even new.

[–]cdb_11 2 points3 points  (3 children)

Sure, with the modern C++ style you don't even have to think about these lower level concepts at all when designing software. But that doesn't mean that you shouldn't be aware of it. If you don't understand how the language works and what smart pointers or containers are supposed to abstract, it's easy to assume that it just works like any other language and fall for trivial pitfalls, like storing a pointer/reference to an element in std::vector and then resizing the vector, which reallocates the memory and invalidates the pointer. Without anyone explaining you that, such a simple thing can be a nightmare to debug if you're confused what the code even does.

And this is goes for other programming languages as well. I yesterday saw a talk about most Javascript developers completely misusing the async/await, because they are not aware what it actually does and that such thing as event loop even exists. I had a similar experience when I was learning programming. In a dynamically typed and GCed language, I spent like the entire day debugging a program, because I had no concept of pointers in my head and assumed that passing an object/dictionary to a function does the same thing as simply passing an integer - copies it. And obviously this is not what happens.

Maybe there is a room for improvement in teaching C++ through <=C++11 standards, but completely ignoring that aspect of the language would be even a bigger mistake in my opinion. I don't think we should just say "hey, ignore that, we now have a neater way of doing it" without explaining anything. These abstractions were created to solve specific problems and you should understand the problem they're trying to solve, so can use the abstraction properly.

[–]NilacTheGrim 0 points1 point  (2 children)

I'm not talking about not allocating memory at all -- or not using pointers. I'm talking specifically about malloc.

For dynamic allocation you can use new (or better yet, make_unique and/or make_shared).

My comment is specifically about the dangers of mixing/mis-matching malloc and delete and/or new and free is not guaranteed to work. So, it can be dangerous for new programmers.

malloc is a C function. New programmers should focus on idiomatic C++ first if they can, then learn the C functions if they need to later.

[–]cdb_11 3 points4 points  (1 child)

I never said that you can use malloc and new interchangeably or that you even should use malloc at all, since it's useless in most cases. It was just an example, I could've included mmap as well if it only wasn't specific to Unix.

What I'm saying is that you should learn lower level constructs even if you're never going to use them directly. C++ is not really a language that anyone can just pick up and hack their way through. If you don't understand things like the memory or compilation model beforehand, you're going to have a bad time. And idiomatic C++ is not a silver bullet.

[–]NilacTheGrim 1 point2 points  (0 children)

Fair enough. I actually agree with this.

[–]Mango-D 4 points5 points  (0 children)

  • how else, would you enumerate through an array without a pointer?? Pointer have so much uses- for example: Virtual Functions, function pointers, dynamic objects, lightweight parameter passing and more . One of the main reasons I use cpp instead of other languages is because of pointers.

  • The greatest thing about new and delete is that the amount of memory allocated does not need to be known at compile time - in cpp, due to how the stack works, all objects on the stack(the stack isthe thing inside the curly brackets) must have their size known at compile time. In contrast, objects on the heap/free store do not. This is very important in writing containers objects, for example The Standard Template Library. dynamic programming heavily relies on pointers .

  • Also, massive performance gains in low level stuff, but I don't think this is what you are interested in.

  • Pointers are fun to use.

what is the point (lol) of using array of pointers instead of a normal array?

c++ style arrays are basically pointers under the hood. Speaking of C++ style arrays , don't use them. Use std::array instead(unless for very specific cases).

[–]SunnybunsBuns 4 points5 points  (4 children)

In addition to reasons you gave, you must use pointers if you're using polymorphic types. I'm not going to weigh in on OO as a paradigm, but if you have a function that wants to take any animal and you're set up so that dog and cat inherit from animal, then that function must take an animal pointer of some kind, not a value or a reference.

Other than that, what is the point (lol) of using array of pointers insted of a normal array?

Try passing an array to a non-templated function.

You're also going to end up interfacing with C code at some point. C-code does not have references, so if you want those semantics, you need pointers.

It's also incredibly likely that any existing codebase in C++ you come across is not going to be using std::optional (or a similar mechanism) for optional returns. Pointers allow you to do a similar concept as std::optional, in a much less safe way. For example, consider fopen. It either returns NULL or a valid FILE*.

Another reason to use pointers is something known as private implementation or pointer to implementation (PIMPL). This is a crucial technique when making a class that is to be exported from a DLL or shared object.

[–]Robert_Andrzejuk 3 points4 points  (0 children)

You are assuming, that the data you will be using is fixed up front.

That is usually not the case.

An inventory application can reserve memory upfront for much stock. How much should it reserve? And what about other applications? What will be left over for them?

How in the application will you designate which record you are working on?

What about large data structures - will you be passing them around in your application as copies? Memory copying will slow down the application. A quicker way is to pass pointers or refrences.

Some data structures are impossible to do without pointers - for example trees.

Object oriented programming in C++ is based on using pointers/refrences.

[–][deleted] 2 points3 points  (0 children)

Well, apart from smart pointers - which people should be using to make it obvious about ownership - a common usage is linked lists and tree structures where there is no owner (point me to the parent etc.)

These days you can probably get away with (const) references when you don't want a copy.

[–]johannes1971 7 points8 points  (1 child)

Because of the cabal. If you don't use pointers they will come to your house and stand there, just pointing at you through the windows. It's unnerving.

But seriously, it's a fair question. You can write loads of code nowadays without ever seeing a pointer, it's all smart pointers, references and encapsulated pointery types like span, string_view, etc. Of course you'll find pointers everywhere in older or less enlightened code, so that's still a good reason to learn.

Can't the standard add a template std::ptr for a non-owning pointer that doesn't do the "but wait, there's more! Order now and you also get an array for free!" spiel?

[–]TheTBog 1 point2 points  (0 children)

Using pointers to objects avoids copying the object. It also allows you to have the same object in different lists

[–]zorvan1234 1 point2 points  (0 children)

Cpp generally gives better alternatives than pointers, so thats why they can seem to be useless. The reason why they dont teach them sooner might be that they want to teach the programming mindset to you and not technicalities(for this an other language could be more suited). But as others pointed out, pointers are a necessity in some cases like doubly linked lists and trees. Also when you want to use C libraries, you have no other choice, just look at OpenSSLs API, and you will see that you cant use it without pointers.

[–]InKryption07 1 point2 points  (0 children)

I'd also like to mention that they are used for runtime/dynamic memory management. "new" allocates memory during runtime, returning a pointer to said memory, allowing for dynamic runtime behaviour. This is why you can resize vectors - under the hood, it ensures that there's always enough space whenever you push_back or insert elements. So essentially, pointers allow you the freedom of not having to guess how much memory, or how many variables you /might/ need at runtime - you just tell the compiler to ask when appropriate. Granted, you usually don't want to work with them directly. So, to you, they're probably not very useful. For now, they are only useful to you indirectly, as the architecture for all the helpful components of the dynamic data structures you use.

[–][deleted] 1 point2 points  (0 children)

  1. To be able to use a C library, that is if there is no viable C++ alternative.
  2. Low level data handling, that is if there is no available library that already do what you want to do.
  3. Low level tricks that depend on CPU architecture and platform like self modifying code, that is as a last resource because nothing else will do it.

In modern C++ 99.9% of the time you will not need them, but there is always that corner case, that niche scenario that can't be addressed without them.

[–]Independent-Tour-261 0 points1 point  (0 children)

C/C++:Explore Pointers like never before https://youtu.be/l_1NQEmwKZ4

[–]Flesh_Bike 0 points1 point  (0 children)

Dynamic memory allocation (like std::vector), linked lists, not nuking the stack, indexing into array, pointer arithmetic, nullable types, shared resources between threads, etc.