C++ pointers: why we need them, when we use them, how they differ from accessing to object itself

Even though most programmers understand what is the difference between objects and pointers to them, sometimes it is not entirely clear, which of the ways of accessing the object to choose. We have tried to answer this question below.


I’m coming from a Java background and have started working with objects in C++. But one thing that occurred to me is that people often use pointers to objects rather than the objects themselves, for example this declaration:

Object *myObject = new Object;

rather than:

Object myObject;

Or instead of using a function, let’s say testFunc(), like this:


we have to write:


But I can’t figure out why should we do it this way. I would assume it has to do with efficiency and speed since we get direct access to the memory address. Am I right?


By the way, we should note, that pointers in Java are not used explicitly, e.g. a programmer cannot access to object in code through a pointer to it. However, in Java all types, except base, are referenced: accessing to them goes by the link, although you cannot explicitly pass the parameter by link. Besides that, new in C++ and Java or C# are different things.

In order to give a slight idea about the pointers in C++ , we’ll give two similar code fragments:


Object object1 = new Object(); 
//A new object is allocated by Java
Object object2 = new Object(); 
//Another new object is allocated by Java

object1 = object2; 
//object1 now points to the object originally allocated for object2
//The object originally allocated for object1 is now "dead" – 
//nothing points to it, so it
//will be reclaimed by the Garbage Collector.
//If either object1 or object2 is changed, 
//the change will be reflected to the other

The closest equivalent to this, is:


Object * object1 = new Object(); 
//A new object is allocated on the heap
Object * object2 = new Object(); 
//Another new object is allocated on the heap
delete object1;
//Since C++ does not have a garbage collector, 
//if we don't do that, the next line would 
//cause a "memory leak", i.e. a piece of claimed memory that 
//the app cannot use 
//and that we have no way to reclaim...

object1 = object2; 
//Same as Java, object1 points to object2.

Let’s see the alternative C++ way:

Object object1; 
//A new object is allocated on the STACK
Object object2; 
//Another new object is allocated on the STACK
object1 = object2;
//!!!! This is different! 
//The CONTENTS of object2 are COPIED onto object1,
//using the "copy assignment operator", the definition of operator =.
//But, the two objects are still different. 
//Change one, the other remains unchanged.
//Also, the objects get automatically destroyed 
//once the function returns...

Are we getting a gain in speed, accessing directly to memory?

Actually, not at all. Pointers are usually used for the access to heap while the objects are located in stack – this is a simpler and quicker structure. If you are a beginner, we have for you some material in which we tell in detail what is a stack and a heap.

Strictly speaking, this question combines two different issues. First: when do we use dynamic memory allocation? Second: when is it better to use pointers? Sure, we won’t do without common words that you must always choose the most appropriate tool for the job. Almost always there is better realization than using manual dynamic allocation (dynamic allocation) and/or raw pointers.

It’s very unfortunate that you see dynamic allocation so often. That just shows how many bad C++ programmers there are.

In a sense, you have two questions bundled up into one. The first is when should we use dynamic allocation (using new)? The second is when should we use pointers?

The important take-home message is that you should always use the appropriate tool for the job. In almost all situations, there is something more appropriate and safer than performing manual dynamic allocation and/or using raw pointers.

Dynamic allocation

In your question, you’ve demonstrated two ways of creating an object. The main difference is the storage duration of the object. When doing Object myObject; within a block, the object is created with automatic storage duration, which means it will be destroyed automatically when it goes out of scope. When you do new Object(), the object has dynamic storage duration, which means it stays alive until you explicitly delete it. You should only use dynamic storage duration when you need it. That is, you should always prefer creating objects with automatic storage duration when you can.

The main two situations in which you might require dynamic allocation:

  1. You need the object to outlive the current scope – that specific object at that specific memory location, not a copy of it. If you’re okay with copying/moving the object (most of the time you should be), you should prefer an automatic object.
  2. You need to allocate a lot of memory, which may easily fill up the stack. It would be nice if we didn’t have to concern ourselves with this (most of the time you shouldn’t have to), as it’s really outside the purview of C++, but unfortunately we have to deal with the reality of the systems we’re developing for.
  3. You don’t know exactly the array size, that you will have to use. As you know, in C++ have the arrays’ size is fixed. It may cause problems, for instance, while reading user input. The pointer defines only that section of memory, where the beginning of an array will be written, not limiting its size.

If a usage of dynamic allocation is necessary, you should encapsulate it using smart pointer or of another type that supports the idiom “Resource acquisition is initialization” (standard containers support it – it is an idiom, in accordance with which the resource: a block of memory, file, network connection, etc. — are initialized while getting in the constructor, and then carefully are destroyed by destructor). For example, smart pointers are std::unique_ptr and std::shared_ptr


However, there are other more general uses for raw pointers beyond dynamic allocation, but most have alternatives that you should prefer. As before, always prefer the alternatives unless you really need pointers.

  1. You need reference semantics. Sometimes you want to pass an object using a pointer (regardless of how it was allocated) because you want the function to which you’re passing it to have access that that specific object (not a copy of it). However, in most situations, you should prefer reference types to pointers, because this is specifically what they’re designed for. Note this is not necessarily about extending the lifetime of the object beyond the current scope, as in situation 1 above. As before, if you’re okay with passing a copy of the object, you don’t need reference semantics.
  2. You need polymorphism. You can only call functions polymorphically (that is, according to the dynamic type of an object) through a pointer or reference to the object. If that’s the behaviour you need, then you need to use pointers or references. Again, references should be preferred.
  3. You want to represent that an object is optional by allowing a nullptr to be passed when the object is being omitted. If it’s an argument, you should prefer to use default arguments or function overloads. Otherwise, you should prefer use a type that encapsulates this behaviour, such as std::optional (introduced in C++17 – with earlier C++ standards, use boost::optional).
  4. You want to decouple compilation units to improve compilation time. The useful property of a pointer is that you only require a forward declaration of the pointed-to type (to actually use the object, you’ll need a definition). This allows you to decouple parts of your compilation process, which may significantly improve compilation time. See the Pimpl idiom.
  5. You need to interface with a C library or a C-style library. At this point, you’re forced to use raw pointers. The best thing you can do is make sure you only let your raw pointers loose at the last possible moment. You can get a raw pointer from a smart pointer, for example, by using its get member function. If a library performs some allocation for you which it expects you to deallocate via a handle, you can often wrap the handle up in a smart pointer with a custom deleter that will deallocate the object appropriately.

Original source – stackoverflow.com

4 thoughts on “C++ pointers: why we need them, when we use them, how they differ from accessing to object itself

  1. Well ,yes you are right when we compare Java’s way of Handling things with that of C++ things change drastically.Althought there are merits and demerits of using dynamically allocated objects rather than objects created over stack. And you really did give very nice points / rules to consider while choosing type of approach.I personally prefer using smart pointers when I really need the objects to out live their Scope .So that whenever the original pointer goes out of scope it removes allocated memory automatically (RAII).Umm one suggestion I think it would be much better and cleaner if you put those code snippets inside “code” tags rather than quote blocks.. Everything else is awesome.😉


  2. … pointers are cool and very powerful thing, however there could be an issue with pointers as we know of them now. Not, just some easy to handle stuff, but very serious issues that arise from a very simple fact.
    That should be addressed properly and completely, but it seems like those falks like to push stuff under the mat, rather than clean the house of bad apples…….

    Very strange approach, a very very strange one.


  3. … okay this is what I meant when I mentioned the pointer issues, though.
    The pointers are just a variable that holds the address and that address is used in order to access some object that has that address. So far all fair… Yeah, that is right, however there are sum stuff that are easy to be miss used you just punch that address and it could access some areas that it shouldn’t. Now there is a virtual address space, but if you are having issues with that, then your code might be just bad… well, no there is nothing you can do about it.
    At the first moment I was scared about jumps that are used for assembler level, like jz, jnc, etc… if one can influence that that is bad… Although, it tours out that that is protected…
    So! The questions is > “Why that is possible with pointers… like outside of your area… Strange… and where is … hmhhh


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.