53

Here is the code:

int main()
{
    using namespace std; 
    int nights = 1001; 
    int * pt = new int; // allocate space for an int
    *pt = 1001;         // store a value there

    cout << "nights value = ";
    cout << nights << ": location " << &nights << endl;
    cout << "int ";
    cout << "value = " << *pt << ": location = " << pt << endl;

    double * pd = new double; // allocate space for a double
    *pd = 10000001.0; // store a double there

    cout << "double ";
    cout << "value = " << *pd << ": location = " << pd << endl; 
    cout << "location of pointer pd: " << &pd << endl;
    cout << "size of pt = " << sizeof(pt);
    cout << ": size of *pt = " << sizeof(*pt) << endl;
    cout << "size of pd = " << sizeof pd;
    cout << ": size of *pd = " << sizeof(*pd) << endl;

    return 0;
}

Now here is the author's note about the code:

Another point to note is that typically new uses a different block of memory than do the ordinary variable definitions that we have been using. Both the variable nights and pd have their values stored in a memory region called the stack, whereas the memory allocated by the new is in a region called the heap or free store.


Initial Question:

Now my concern is this: the variable pd was create by the keyword new, so it should be stored in the region called heap just like the variable pt, since they were both created by the keyword new.

Am I missing something here? Thank you very much in advance for your inputs.

Revised Question/Follow-up based on the hold:

This question was put on hold by 5 people because they couldn't understand what I was asking. I believe that my question has already been answered but for those who are still not sure about what I was initially asking please read along:

I was unclear about the author's explanation about where the variables and their values were stored in memory. Up to the author explanation, I had a belief that any memory created dynamically (or should I say during runtime after compiling) by using the keyword new gets stored in the heap not the stack.

So, it confused me when he wrote that the variable pd has is value stored in the stack, but again how is that possible if the variable was create during "runtime" with the keyword new, so it should be in the heap, not the stack.

Please try to use the code above as the reference and in particular the **variables (nights, pd, and pt) in your answer so that I can understand it from that code's perspective.

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
rnd809
  • 341
  • 3
  • 10
  • _`int * pt = new int;`_ why not simply `int t = 1001;`? – πάντα ῥεῖ Jun 08 '17 at 08:00
  • 26
    You aren't missing much. And the author of the book mixes implementation details with the semantics of C++ itself. I suggest getting a better book. – StoryTeller - Unslander Monica Jun 08 '17 at 08:01
  • 33
    `pd` is on the stack (holding a pointer), what `pd` points to is on the heap. – Richard Critten Jun 08 '17 at 08:03
  • 44
    -6 is particularly harsh for a well-written question with compilable code. In what way could this question be improved? The fact that the book was written by a muppet is no bearing on the OP, aside from their book selection skills. – Bathsheba Jun 08 '17 at 08:05
  • 3
    @Bathsheba I guess this happened when the question title was written in full caps :) but besides that, it was well formulated indeed – Poul Kruijt Jun 08 '17 at 08:17
  • 8
    I googled "is a pointer on the stack or the heap" and the first result was [this question](https://stackoverflow.com/questions/24380935/where-are-pointers-in-c-stored-on-the-stack-or-in-the-heap/24381070) which answers the OPs immediate question about pointers on the stack/heap. So, lack of research can be a valid claim. – Weak to Enuma Elish Jun 08 '17 at 08:19
  • @πάνταῥεῖ I'm not shouting! lolSorry about that. Also, I can't use int t = 1001; because I'm learning the concept of points and allocating memory at runtime. – rnd809 Jun 08 '17 at 08:29
  • 2
    @Bathsheba Thank you for the support and the empathy lol! It seems like a tough crowd to please. Also, it seems like you dislike my book selection. Can you please recommend me a good C++ book for a beginner? Thank you in advance! – rnd809 Jun 08 '17 at 08:34
  • 2
    @StoryTeller What do you recommend? – rnd809 Jun 08 '17 at 08:35
  • 7
    Have a gander [here](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) – StoryTeller - Unslander Monica Jun 08 '17 at 08:36
  • 1
    @RichardCritten I think you hit the nail on the head. Thanks. Just to be clear: pd variable ----> Stack | pd'value -----> Heap ? – rnd809 Jun 08 '17 at 08:57
  • What book/website is this from? – Fabio says Reinstate Monica Jun 08 '17 at 16:36
  • 1
    @FabioTurati Is C++ Primer Plus....Is actually a great book. When I continure to read along he continues to explain the other side of the story, "delete". Just needed this great forum resources to clear some questions I had and wasn't sure about. Thank You! – rnd809 Jun 08 '17 at 16:44
  • 1
    @Bathsheba I think that this is the famous book C++ Primer by Stephen Prata. – mapreduce_kaz Jun 08 '17 at 17:45
  • 1
    @rnd809: pointers can point at values anywhere in memory. Usually but not always on the heap. – Mooing Duck Jun 09 '17 at 01:55
  • @RichardCritten: We actually can't know. It is not defined by standard when stack/heap has to be used and how. It is just a concept used by the underlying system and shouldn't be linked to the language. It would even be in respect to the standard if `pd` was on the heap and its local dereference would be placed on the heap. Of course this would not make much sense. but it would be conform with the language specification. And thats why I think its wrong to say "In C++ X is on the heap while y will be on the stack"... – dhein Jun 09 '17 at 09:16
  • @Zaibis I know that the standard does not require stack/heap and is just a concept / implementation detail. However believe in trying to answer questions at the level of understanding of the person asking, too much information in one lump can confuse as much as help . Others can hopefully complete the answer when the question as asked has been answered. – Richard Critten Jun 09 '17 at 10:14

5 Answers5

94

The pointer variables pt and pd are stored on the stack. The values they point at, allocated with new, are stored on the heap.

If I write a sign with an arrow labelled "lake", it doesn't mean that the sign itself is a lake, nor that it must be mounted in a lake. Rather, it should be mounted on solid ground, pointing in the direction of the lake.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 9
    Excellent lake analogy. I'm going to steal it! – Weak to Enuma Elish Jun 08 '17 at 08:21
  • 20
    Nitpicking: The c++ standard doesn't mention the concept of a _stack_ or _heap_ at all. They have a concept of local and dynamic storage IIRC. – πάντα ῥεῖ Jun 08 '17 at 08:47
  • @Lundin I like analogies. Thank you for that. Just one quick question to solidify my understanding: The actual variable names.... "pt", "pd" and "night" are all stored in the stack. Just the variable right? Now, the value that they carry or hold are stored where? I apologize if my question is redundant. If someone can do something like this I would be happy: nights variable --> Stack or Heap? | nights's value ---> ? pd variable ---> Stack or Heap? | pd's value ---> ? pt variable ---> Stack or Heap? | pt's value -----> ? – rnd809 Jun 08 '17 at 08:48
  • 28
    @πάνταῥεῖ So what? If the C++ standard doesn't mention it it doesn't exist? The reason stack and heap aren't mentioned in the standard is simply because such things are outside the scope of the programming language. All real-world computers use segments called stack and heap regardless. (Although of course local variable are not necessarily stored on the stack, they could be stored in registers.) – Lundin Jun 08 '17 at 08:52
  • 2
    @rnd809 Their values (the actual variables) are all stored on the stack. In case of pointers, the values happen to be addresses. If you follow those addresses, you'll end up in memory allocated elsewhere, in this case on the heap. – Lundin Jun 08 '17 at 08:54
  • @Lundin Thank you. I needed an explanation like this. Very simple :) Simplicity sometimes is very difficult to achieve. – rnd809 Jun 08 '17 at 08:58
  • 2
    Because, given that the size of the message within the sign doesn't exceed a certain value, the sign will never change size. Whereas, a lake can be different shapes and sizes – CraigR8806 Jun 08 '17 at 13:17
  • 2
    @Ludin It is important to be correct, and not to break encapsulation of the language. It is abstracted for a reason. Language does not guarantee where on the bare metal variable lives. One should be aware of this. Breaking this encapsulation leads to custom language extensions. It is different saying "those variables have such storage, which is usually implemented this way", instead of "In c++ this is here, and this is there." because it might not be true. – luk32 Jun 08 '17 at 13:17
  • 2
    But often people do need a model of whats going on underneath. The C++ Standard memory model may be more correct (or less incorrect!) but it is rather dry and arcane. Most actual implementations have actually stacks and heaps. – Nick Keighley Jun 08 '17 at 13:20
  • 3
    @πάνταῥεῖ The `C++` standard mentions the term `stack` all over the place. The `Free Store` is just `C++` terminology for *the heap*, same concept but *the heap* is a general computing term for a place to get arbitrary chunks of memory. It contrasts with `stack` that is strictly FILO organized. – Galik Jun 08 '17 at 13:51
  • 7
    The dark side of c++ is the language police. – 0kcats Jun 08 '17 at 14:33
  • 3
    Wait, *all* real world computers use segments called stack and heap? I was pretty sure there was at least one that didn't, and actually allocated automatic storge variables in a linked list of memory allocated on the "heap" – Yakk - Adam Nevraumont Jun 08 '17 at 17:30
  • 1
    @luk32 It is abstracted for a reason indeed: to create a normative definition of how a C++ program should run. It is not abstracted so that everyone needs to use those words. Chaining ourselves to the abstract specification is like demanding we only talk about rape and murder using the exact precise definitions provided by our legal system. These are concepts that can be understood years before we develop the intellectual capacity to slog through the legalese nuances of those two words. – Cort Ammon Jun 08 '17 at 22:25
  • @Yakk If you're not being facetious (it's hard to tell), there were (are) [Lisp Machines](https://en.wikipedia.org/wiki/Lisp_machine) and other kinds of modern architecture and implementation that don't rely on the common stack/heap duality -- but then, this question is about C++ and the C family of procedural languages is designed for von Neumann, procedural architecutres with code-data separation, so "all" is within a certain scope – cat Jun 08 '17 at 22:46
  • @Galik I just feel that if you point out that the standard mentions the term `stack`, you should also point out that the standard describes a [class template _called_ `stack`](https://timsong-cpp.github.io/cppwp/n4140/stack), which is neither a representation of the traditional stack, nor required to be stored on it. – Justin Time - Reinstate Monica Jun 08 '17 at 23:59
  • 2
    @JustinTime Yes I should have been more clear that the standard refers to a program stack in addition to the class template. For that matter there are also functions to create a `heap` data structure in the standard library but the `heap` data structure is an unrelated concept to *heap storage* as a dynamic resource for memory. I think maybe people confuse those two also. – Galik Jun 09 '17 at 00:07
  • 1
    @cat no I am talking about a machine that stored the C/C++ automatic storage in linked lists on something heap like. C/C++ runs on much strange hardware. – Yakk - Adam Nevraumont Jun 09 '17 at 01:08
  • 3
    @Lundin: One of the reasons that the C++ language does NOT use stack and heap, is that those are implementation details. If you compile this code with optimizations on, a good compiler will NOT use the heap, it'll simply put another double on the stack (or even a register). So, the accurate way of describing this would be that *worst case* `pd` ends up on the stack and its pointed value on the heap. Emphasis on *worst case*. – Matthieu M. Jun 09 '17 at 06:31
  • 2
    @MatthieuM. My answer addresses the most common system implementation. _Again:_ It doesn't matter what C++ says or does not say, because where variables end up in memory is outside the scope of the programming language. Furthermore, this is directed to a beginner who need to grasp the basic concepts. They need not concern themselves with how compilers optimize heap access, stack-less/heap-less systems and other such more advanced topics. – Lundin Jun 09 '17 at 06:36
19

The only mistakes the author have made are

  1. Not calling delete once use of the pointers is finished.

  2. The repeated use of endl is questionable. Use \n instead.

  3. using namespace std;, whilst often used in tutorials to achieve brevity is ill-advised in production code, particularly in headers.

  4. Using int * pt = new int; *pt = 1001; in place of int* pt = new int(1001); is questionable since the way the author has it, *pt is in an unnecessarily uninitialised state between two statements. That makes your code vulnerable to instabilities to creep in.

  5. (Minor). You should always think about the possibility that new can throw a std::bad_alloc exception if the allocation fails.

I wouldn't worry about the terms stack and heap too much; they are language implementation concepts not part of the language itself. Prefer the terms automatic and dynamic storage duration. That's what the C++ standard uses, so why invent a whole load of alternative terminology?

Really I'd burn the book and get yourself a copy of Stroustrup.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Got my upvote for pointing the OP at storage duration, alone. Fantastic answer. – StoryTeller - Unslander Monica Jun 08 '17 at 08:19
  • @Bathsheba Thank you for the answer! – rnd809 Jun 08 '17 at 08:55
  • 12
    I'm not sure I agree with #5. The whole point of throwing an exception (as opposed to returning an error code, C-style) is that you don't *have* to write handling code for the exception. If an attempt to allocate memory fails—which is an unexpected event in the typical case, and you can't even write a handler for if you wanted to—then the exception is thrown and the program is terminated. – Cody Gray - on strike Jun 08 '17 at 09:11
  • @CodyGray: I've changed the wording slightly but even so, I think your point still stands. I'll plus one it. – Bathsheba Jun 08 '17 at 09:24
  • 6
    + for the last comment about burning the book - this book seems to be teaching a range of bad habbits which would fail peer reviews. – UKMonkey Jun 08 '17 at 09:27
  • 1
    I would remove point 3, after all this IS a tutorial, and not production code. – DrMcCleod Jun 08 '17 at 12:28
  • 1
    @DrMcCleod: I wouldn't. I disclaim sufficiently (I think), and it's always something to bear in mind when reading tutorials. – Bathsheba Jun 08 '17 at 12:29
  • To add a bit of context - it seems to be from "C++ Primer Plus" by Stephen Prata. The book has a section talking about the Out Of Memory - situation right below the quoted section and continues to introduce `delete` after that. (according to extracts on google books, I don't have a copy to check) – Hulk Jun 08 '17 at 12:34
  • 3
    The book gets worse. Why would it introduce `delete` after `new`, with some code in between? Unless the code is watermarked "absolutely rubbish" then that behaviour is reprehensible. Even more so if read by folk who are used to languages with garbage collectors. – Bathsheba Jun 08 '17 at 12:48
  • 1
    Did you mean brevity instead of clarity? – Deduplicator Jun 08 '17 at 13:32
  • @Deduplicator: Yes, brevity is a much better word. Thank you. – Bathsheba Jun 08 '17 at 13:46
  • While the verdict on the quality of the code example is fine, this answer says not a single thing about the actual question and the yellow quote in it. Aside from the example code, the actual *content* this question is about is absolutely correct, and not badly explain either. – AnoE Jun 08 '17 at 14:54
  • @AnoE I believe I allude to the yellow stuff: it's largely hogwash as it talks about heaps and stacks and free stores, none of which are part of the definition of C++. My point 4 and my penultimate paragraph deal with that. But your points are valid, the downvoting mechanism should be used to express that. Unfortunately this epotomises the issues I have with the 10, 0 / -2, -1 upvote / downvote asymmetry that the SE engine has. – Bathsheba Jun 08 '17 at 15:01
  • 8
    Why do you object to the use of endl? Isn't that a tool for writing the os-appropriate endline? Remember that windows uses CRLF, so '\n' is not a correct line ending. – Benubird Jun 08 '17 at 15:04
  • 1
    @Benubird: It flushes the buffer which can hit performance.. Best rely on the runtime library / OS to buffer output. – Bathsheba Jun 08 '17 at 15:07
  • Fair enough, @Bathsheba; all you wrote is factually correct. I feel that the poster displayed that he is not aware of the basics of memory management in computers (i.e., stack/heap as general concept, not specific implementation); and I feel that pointing out the difference of "where is the pointer stored" vs "where does the pointer point" is the most helpful (to this specific question) answer. You are right, and thankfully so, to not take the -1 too much to heart; it is a "human-neutral" mechanism that allows a bit of opinion on the voters side. :) – AnoE Jun 08 '17 at 15:20
  • @AnoE: I only wish the downvote reduced the answerer's reputation by -10 (or at least -5), rather than -2 I've never understood the asymmetry. The -1 taken by the downvoter, plus the +125 necessary reputation for that action, is enough to guard against trolls. – Bathsheba Jun 08 '17 at 15:21
  • 4
    @Benubird `\n` is correct regardless of OS; part of the reason why we have text mode and binary mode is to abstract away line ending differences. (And all `endl` does is to write a `\n` followed by a flush.) – T.C. Jun 08 '17 at 17:53
  • Is "heap" really an implementation concept? It doesn't actually describe anything about any implementation, its usual meaning begins and ends with "any memory allocated by malloc/new/etc". No implementation actually uses an actual "heap" (the priority queue data structure) for the "heap" (the dynamic memory allocation concept). – Random832 Jun 09 '17 at 05:07
16

Pictures will help.

Automatic storage (stack)                      Dynamic storage (heap)
-------------------------                      ----------------------

Item        Address        Value               Address        Value
----        -------        -----               -------        -----          
nights      0xff001000     1001               
    pt      0xff001004     0x00b0fff0 ------>  0x00b0fff0     1001
    pd      0xff00100c     0x00b0fff4 ------>  0x00b0fff4     10000001.0            

The objects nights, pt, and pd all have auto storage duration. On most implementations, this means they are allocated from the runtime stack. The object nights lives at address 0xff0010001 and stores the value 1001. The object pt lives at address 0xff0010004 and stores the address of a dynamic object created by new, which is 0x00b0fff0. The object pd lives at address 0xff00100c and stores the address of another dynamic object created by new, which is 0x00b0fff4.

The heap objects at addresses 0x00b0fff0 and 0x00b0fff4 store the values 1001 and 10000001.0, respectively.

Edit

FWIW, I wrote a dumper utility some time ago that dumps out object addresses and contents; given the code

#include <cstdio>
#include "dumper.h"

using namespace std;

int main( void )
{
  int nights = 1001;
  int *pt = new int;
  *pt = 1001;
  double *pd = new double;
  *pd = 1000001.0;

  char *names[] = { "nights", "pt", "pd", "*pt", "*pd" };
  void *addrs[] = { &nights, &pt, &pd, pt, pd };
  size_t sizes[] = { sizeof nights, sizeof pt, sizeof pd, sizeof *pt, sizeof *pd };

  dumper( names, addrs, sizes, 5, stdout );

  return 0;
}

I get the output

       Item         Address   00   01   02   03
       ----         -------   --   --   --   --
     nights  0x7fff9efe7c6c   e9   03   00   00    ....

         pt  0x7fff9efe7c60   10   20   50   00    ..P.
             0x7fff9efe7c64   00   00   00   00    ....

         pd  0x7fff9efe7c58   30   20   50   00    0.P.
             0x7fff9efe7c5c   00   00   00   00    ....

        *pt        0x502010   e9   03   00   00    ....

        *pd        0x502030   00   00   00   00    ....
                   0x502034   82   84   2e   41    ...A

In this case, the addresses are real. On my system (x86_64/Linux SLES-10), stack addresses start high and grow "downwards" (towards lower addresses), while heap addresses start low and grow "upwards" (towards higher addresses).

x86 is little endian, meaning the addressed byte is the least significant byte; multi-byte objects need to be read from right to left.


  1. All addresses are made up out of thin air and are not meant to represent any real-world implementation or architecture.

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • You might want to make your stack and heap addresses more obviously different, for a moment I thought `pt` was pointing to itself. – zwol Jun 08 '17 at 16:03
  • @JohnBode Thanks Bro! This was very nicely done. By the way, how did you constructed that image? Is it an IDE feature that produced it for you after compiling the source code or what? Many blessings your way. – rnd809 Jun 08 '17 at 16:56
  • @rnd809: Manually typed it all in, formatted as a code snippet (basically made sure each line had four leading blank spaces). – John Bode Jun 08 '17 at 17:06
  • @rnd809: Added some output from code showing the actual addresses on contents on my system. – John Bode Jun 08 '17 at 17:22
  • @JohnBode Got it! That's gold. – rnd809 Jun 08 '17 at 17:49
15

Now my concern is this: the variable pd was create by the keyword new, so it should be stored in the region called heap just like the variable pt, since they were both created by the keyword new.

No, it was not. The code is:

 double * pd = new double; // allocate space for a double

This is no different from:

double * pd;
pd = new double;

So clearly, pd itself is not created by the new operator, only the value it holds is. But he's talking about pd, not its value.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • 2
    The author is talking about values. So, yes, value of `pd` is an address and it is stored on stack. But it's value is an address which points to memory on heap. – zoska Jun 08 '17 at 14:55
  • 1
    @zoska The author was indeed talking about values. So like you said, "pd is an address and it is stored on stack. But it's value is an address which points to memory on heap." I think that clears things up. – rnd809 Jun 09 '17 at 18:26
  • @DavidSchwartz Thanks you sir! – rnd809 Jun 09 '17 at 18:29
  • @zoska The author is not talking about values. Suppose you have a variable `j` with value 5 and address 10. If you say "where the value is stored", you're talking about 10, not 5. The text is "have their values stored in", so it's not talking about the value but where that value is stored, that is, the variable itself that holds the value. If you talk about where my car is stored, you're talking about my garage, not my car. – David Schwartz Mar 09 '18 at 19:10
7

The pd variable is stored in stack memory, however the memory location where pd points to is allocated in heap memory. I think author wanted to emphasize exactly this difference between these concepts.