5

I am learning C++ by reading a textbook. The "objects and pointers" part says, that declaring a pointer to an object like this :

SomeClass *ptrMyClass;

does nothing by itself. Only after defining an instance of Class does it make sense, like this :

SomeClass *ptrMyClass;
ptrMyClass = new SomeClass;

Or by combining these together in :

SomeClass *ptrMyClass = new SomeClass;

My question is, why do we have to create an instance of SomeClass on the heap by using 'new' ? So far in the book, pointers always pointed to 'normal' variables ( like int, float... ) that weren't created by using 'new'. Thank you.

trincot
  • 317,000
  • 35
  • 244
  • 286
James C
  • 901
  • 1
  • 18
  • 38
  • You don't have to. Normally you must avoid it. Anyway, both, stack and heap allocation have its pros and cons. – Ivan Aksamentov - Drop Feb 06 '14 at 23:55
  • @Drop - do you mean normally I should avoid creating objects on heap ? Why does the book teach "objects and pointers" by creating objects with 'new' then ? There must be a good reason. – James C Feb 07 '14 at 00:00
  • 1
    (1) Use heap only if you have to, otherwise use stack allocation. (2) We tend to use smart pointers and STL facilities instead of using raw `new`/`delete`. (3) You can have pointer to an object of class type allocated on stack, same way as you do it with `int`. So as you can have `int` allocated on heap. (4) No man can know all about C++, even Stroustrup. So there is no absolute book. Always be a critic of what you're reading. Books for beginners often (over)simplify things and even explain it wrong. That's okay, you can always refresh and reload your knowledge later ;) – Ivan Aksamentov - Drop Feb 07 '14 at 00:06
  • 1
    `Why does the book teach "objects and pointers" by creating objects with 'new' then` First thing that comes in mind: author comes from C#/Java world ;) – Ivan Aksamentov - Drop Feb 07 '14 at 00:11
  • 1
    Since both the question and the answers are discussing the heap, I'm just going to leave [this](https://stackoverflow.com/a/9182244/212858) here for future reading. The heap is an implementation detail of the free store which is where we do dynamic allocation, and IMO it's the "dynamic" part which is interesting and relevant, not the "heap" bit. – Useless Sep 06 '21 at 13:00

5 Answers5

4

There are two main ways of instantiating objects in C++: stack and heap (or free store). For example:

void func()
{
    // On the stack:
    Widget blah;

    // On the heap:
    Widget * foo = new Widget;
    delete foo;
}

The advantage of stack objects/variables is that they tend to be a little a faster to allocate/access, and they are slightly easier to work with. However, the stack is a limited size, and the data is usually limited to local scope (with the exception of global variables, which are usually inadvisable). That is, the blah object in the example above will be automatically destroyed as soon as func() ends. There's nothing you can do about that. Any pointers to stack objects/variables therefore become invalid (aka 'dangling') when the original item goes out of scope.

The heap is (typically) much bigger, so it can cope with a lot more data than the stack. It tends to be slightly slower, but it has the advantage of letting you reallocate things at run-time. By contrast, stack objects/variables (and especially arrays) are fixed at compile-time.

Additionally, after an object has been allocated on the heap, you can leave it there for as long as you need it, maintaining valid pointers to it. In the past, you would have to call delete eventually to avoid a memory leak. In modern C++, smart pointers are encouraged instead (e.g. std::shared_ptr).

As an additional note, it gets slightly more complex when declaring members of a class. If the object is instantiated on the stack, then any of its direct members (i.e. members by composition) will be on the stack too. If the object is instantiated on the heap, then all of its members will be on the heap.

Peter Bloomfield
  • 5,578
  • 26
  • 37
2

My question is, why do we have to create an instance of SomeClass on the heap by using 'new' ?

You don't. You can dynamically create an object with new. Alternatively you can get a pointer to an existing object

SomeClass* ptrMyClass1;     // An uninitialized pointer.

                            // If an automatic object its value is indeterminate and
                            // You have not defined what it points at. It should not
                            // be used (until you explicitly set it to something).

                            // If a static object then it is initialized to NULL
                            // i.e. Global (or other static storage duration object).

SomeClass* ptrMyClass2 = new SomeClass; // A pointer to a dynamically 
                                        // allocated object.

SomeClass  objMyClass3;                 // A normal object
SomeClass* ptrMyClass4 = &objMyClass3;  // A pointer to a normal object
Martin York
  • 257,169
  • 86
  • 333
  • 562
2

Why create an instance of a class in the heap

There is a case when you have to do this kind of stuff.

When you're using an abstract class with no concrete methods, and classes that inherit from that abstract class (in Java or PHP world we would talk about inheritance from an interface):

class IMyAbstractClass
{
public:
    virtual int myFunction(void) = 0;
};

class MyInheritedClass : public IMyAbstractClass
{
public:
    int myFunction(void)
    {
        // doSomething
        return 0;
    }
};

If you need to refer to instances of inherited classes, by the abstract class they inherit from, then the syntax is:

IMyAbstractClass * myInstance;
myInstance = new MyInheritedClass;

So what does it allow you to do?

After having declared your object this way, you can pass it to another object's constructor as being an instance of IMyAbstractClass:

AnotherClass anotherObject(myInstance);

This constructor being coded like that:

class AnotherClass
{
public:
    AnotherClass(IMyAbstractClass * instance)
    {
        // doSomething
    }
};

Real life example anywhere?

This kind of behavior is used in the Strategy design pattern.

Jivan
  • 21,522
  • 15
  • 80
  • 131
1

why do we have to create an instance of SomeClass on the heap by using 'new' ?

You don't have to. You can also reference an instance created on the stack:

SomeClass some;
SomeClass* ptrMyClass(&some);
justin
  • 104,054
  • 14
  • 179
  • 226
1

Modern theorists dislike to use term "heap" in relation to dynamic allocation of objects. It's not clear how this term is coined but it conflicts with the name of so-called heap-like structures (a set with particular properties, a pile). C++ standard doesn't use such term.

The main difference between static, automatic and dynamic allocation is self-explnatory if such terms are used. Statically allocated objects have predetermined identity, even if in given context. They are named, their count and size fully defined at compile time.

Automatically created objects are result of a entry to a function or code block. Their names are known as local variables. Within particular block they have identity predefined by program, but every recursive or parallel call to fuction would create another copy automatically. They are destroyed at exit.

Dynamically allocated objects can be created as many times as programmer desires and decision whether to create one or not and how many can be made during execution, no new stack frame is required. Those objects can't be named, but can be referenced and some relation between locations of objects or subobjects can be deduced by pointer arithmetics. One could say that dynamic allocation can create a pile of objects, hence a result of any pointer arithmetic operations applied to objects which are not subobjects of same object is undefined.

In C++ the only way to create array of size unknown to programmer is dynamic allocation. C99 had portable analig of 'alloca' function, known as Variable Length Array, which allocates such array within stack frame. Some popular C++ compilers support VLA as an extension, to dismay of code checkers and confusion of beginners.

Swift - Friday Pie
  • 12,777
  • 2
  • 19
  • 42
  • The first paragraph is in sore need of evidence in the form of references. Yes, there’s a name conflict, but so what? Lots of similar name conflicts exist and, while not ideal, they don’t really cause confusion in practice. – Konrad Rudolph Sep 06 '21 at 12:13
  • 1
    There's no heap mentioned in the standard, the heap isn't the only possible free store, and it tells you nothing about object lifetime. Perhaps this makes me a "modern theorist", but I definitely prefer static vs automatic/local vs dynamic allocation for general use. – Useless Sep 06 '21 at 12:20
  • @KonradRudolph this was discussed before, https://stackoverflow.com/questions/1699057/why-are-two-different-concepts-both-called-heap (and see item it "dupes"). Mathematics doesn't suffer ambiguity, being based on Aristotle's logic. Theory of programming is practically an area of applied mathematics. – Swift - Friday Pie Sep 06 '21 at 12:21
  • @Useless heap trees were used as garbage collector support structures, that could be the reason. And, in away, heap by itself doesn't determine location and life length, is only partially ordered afaik. Life length if dynamically allocated object ends when we remove it from that "pile" (wether OS does such cleanup if program would exit, is not defined and some embedded OSes actually don't) – Swift - Friday Pie Sep 06 '21 at 12:32
  • @Useless Oh [we are in agreement](https://stackoverflow.com/a/10157210/1968) that *in the context of the C++ standard’s memory model*, there’s no heap. But this has got nothing to do with the data structure of the same name, and it doesn’t preclude talking about heap storage when discussing low-level details outside of the context of the C++ standard. – Konrad Rudolph Sep 06 '21 at 12:32
  • @KonradRudolph https://en.cppreference.com/w/cpp/algorithm/make_heap – Swift - Friday Pie Sep 06 '21 at 12:34
  • @Swift-FridayPie “Mathematics doesn't suffer ambiguity, being based on Aristotle's logic. Theory of programming is practically an area of applied mathematics.” — that’s … nonsense. Mathematical writing is *chock full* of ambiguous definitions and overloaded naming — sometimes even within a given domain! That’s why good papers clearly state *their* definitions up-front. – Konrad Rudolph Sep 06 '21 at 12:34
  • @Swift-FridayPie I know that. How’s that related to my comment? – Konrad Rudolph Sep 06 '21 at 12:35
  • @Swift-FridayPie At any rate, I may be overlooking it but I don’t see any evidence in the link you’ve posted (nor in the duplicate) that would show that any significant number of theorists specifically dislikes using the term. – Konrad Rudolph Sep 06 '21 at 12:37
  • It doesn't preclude talking about heap storage - I just think it's a poor choice for beginners because it's uninformative. If I can choose between the relatively clear, unambiguous term (dynamic) and the IMO less-clear, more ambiguous (or anyway more overloaded) one, I'm using the former. – Useless Sep 06 '21 at 12:52
  • @Useless and if to follow Herb Sutter's recomendation, one can speak of freestore or dynamic when talking about creation of ibjects with new expressiin and of heap when creating storage by 'malloc' for future object creation (how its purpose defined in C++). It's not defined if new and malloc use same resources, but malloc creates only a storage - a heap which we can divide between objects later – Swift - Friday Pie Sep 06 '21 at 13:48