Search

6.9 — Dynamic memory allocation with new and delete

The need for dynamic memory allocation

C++ supports three basic types of memory allocation, of which you’ve already seen two.

  • Static memory allocation happens for static and global variables. Memory for these types of variables is allocated once when your program is run and persists throughout the life of your program.
  • Automatic memory allocation happens for function parameters and local variables. Memory for these types of variables is allocated when the relevant block is entered, and freed when the block is exited, as many times as necessary.
  • Dynamic memory allocation is the topic of this article.

Both static and automatic allocation have two things in common:

  • The size of the variable / array must be known at compile time.
  • Memory allocation and deallocation happens automatically (when the variable is instantiated / destroyed).

Most of the time, this is just fine. However, you will come across situations where one or both of these constraints cause problems, usually when dealing with external (user or file) input.

For example, we may want to use a string to hold someone’s name, but we do not know how long their name is until they enter it. Or we may want to read in a number of records from disk, but we don’t know in advance how many records there are. Or we may be creating a game, with a variable number of monsters (that changes over time as some monsters die and new ones are spawned) trying to kill the player.

If we have to declare the size of everything at compile time, the best we can do is try to make a guess the maximum size of variables we’ll need and hope that’s enough:

This is a poor solution for at least four reasons:

First, it leads to wasted memory if the variables aren’t actually used. For example, if we allocate 25 chars for every name, but names on average are only 12 chars long, we’re using over twice what we really need. Or consider the rendering array above: if a rendering only uses 10,000 polygons, we have 20,000 Polygons worth of memory not being used!

Second, how do we tell which bits of memory are actually used? For strings, it’s easy: a string that starts with a \0 is clearly not being used. But what about monster[24]? Is it alive or dead right now? That necessitates having some way to tell active from inactive items, which adds complexity and can use up additional memory.

Third, most normal variables (including fixed arrays) are allocated in a portion of memory called the stack. The amount of stack memory for a program is generally quite small -- Visual Studio defaults the stack size to 1MB. If you exceed this number, stack overflow will result, and the operating system will probably close down the program.

On Visual Studio, you can see this happen when running this program:

Being limited to just 1MB of memory would be problematic for many programs, especially those that deal with graphics.

Fourth, and most importantly, it can lead to artificial limitations and/or array overflows. What happens when the user tries to read in 600 records from disk, but we’ve only allocated memory for a maximum of 500 records? Either we have to give the user an error, only read the 500 records, or (in the worst case where we don’t handle this case at all) overflow the record array and watch something bad happen.

Fortunately, these problems are easily addressed via dynamic memory allocation. Dynamic memory allocation is a way for running programs to request memory from the operating system when needed. This memory does not come from the program’s limited stack memory -- instead, it is allocated from a much larger pool of memory managed by the operating system called the heap. On modern machines, the heap can be gigabytes in size.

Dynamically allocating single variables

To allocate a single variable dynamically, we use the scalar (non-array) form of the new operator:

In the above case, we’re requesting an integer’s worth of memory from the operating system. The new operator returns a pointer containing the address of the memory that has been allocated.

Most often, we’ll assign the return value to our own pointer variable so we can access the allocated memory later.

We can then dereference the pointer to access the memory:

If it wasn’t before, it should now be clear at least one case in which pointers are useful. Without a pointer to hold the address of the memory that was just allocated, we’d have no way to access the memory that was just allocated for us!

How does dynamic memory allocation work?

Your computer has memory (probably lots of it) that is available for applications to use. When you run an application, your operating system loads the application into some of that memory. This memory used by your application is divided into different areas, each of which serves a different purpose. One area contains your code. Another area is used for normal operations (keeping track of which functions were called, creating and destroying global and local variables, etc…). We’ll talk more about those later. However, much of the memory available just sits there, waiting to be handed out to programs that request it.

When you dynamically allocate memory, you’re asking the operating system to reserve some of that memory for your program’s use. If it can fulfill this request, it will return the address of that memory to your application. From that point forward, your application can use this memory as it wishes. When your application is done with the memory, it can return the memory back to the operating system to be given to another program.

Unlike static or automatic memory, the program itself is responsible for requesting and disposing of dynamically allocated memory.

Initializing a dynamically allocated variable

When you dynamically allocate a variable, you can also initialize it via direct initialization or uniform initialization (in C++11):

Deleting single variables

When we are done with a dynamically allocated variable, we need to explicitly tell C++ to free the memory for reuse. For single variables, this is done via the scalar (non-array) form of the delete operator:

What does it mean to delete memory?

The delete operator does not actually delete anything. It simply returns the memory being pointed to back to the operating system. The operating system is then free to reassign that memory to another application (or to this application again later).

Although it looks like we’re deleting a variable, this is not the case! The pointer variable still has the same scope as before, and can be assigned a new value just like any other variable.

Note that deleting a pointer that is not pointing to dynamically allocated memory may cause bad things to happen.

Dangling pointers

C++ does not make any guarantees about what will happen to the contents of deallocated memory, or to the value of the pointer being deleted. In most cases, the memory returned to the operating system will contain the same values it had before it was returned, and the pointer will be left pointing to the now deallocated memory.

A pointer that is pointing to deallocated memory is called a dangling pointer. Dereferencing or deleting a dangling pointer will lead to undefined behavior. Consider the following program:

In the above program, the value of 7 that was previously assigned to the allocated memory will probably still be there, but it’s possible that the value at that memory address could have changed. It’s also possible the memory could be allocated to another application (or for the operating system’s own usage), and trying to access that memory will cause the operating system to shut the program down.

Deallocating memory may create multiple dangling pointers. Consider the following example:

There are a few best practices that can help here.

First, try to avoid having multiple pointers point at the same piece of dynamic memory. If this is not possible, be clear about which pointer “owns” the memory (and is responsible for deleting it) and which are just accessing it.

Second, when you delete a pointer, if that pointer is not going out of scope immediately afterward, set the pointer to 0 (or nullptr in C++11). We’ll talk more about null pointers, and why they are useful in a bit.

Rule: Set deleted pointers to 0 (or nullptr in C++11) unless they are going out of scope immediately afterward.

Operator new can fail

When requesting memory from the operating system, in rare circumstances, the operating system may not have any memory to grant the request with.

By default, if new fails, a bad_alloc exception is thrown. If this exception isn’t properly handled (and it won’t be, since we haven’t covered exceptions or exception handling yet), the program will simply terminate (crash) with an unhandled exception error.

In many cases, having new throw an exception (or having your program crash) is undesirable, so there’s an alternate form of new that can be used instead to tell new to return a null pointer if memory can’t be allocated. This is done by adding the constant std::nothrow between the new keyword and the allocation type:

In the above example, if new fails to allocate memory, it will return a null pointer instead of the address of the allocated memory.

Note that if you then attempt to dereference this memory, undefined behavior will result (most likely, your program will crash). Consequently, the best practice is to check all memory requests to ensure they actually succeeded before using the allocated memory.

Because asking new for memory only fails rarely (and almost never in a dev environment), it’s common to forget to do this check!

Null pointers and dynamic memory allocation

Null pointers (pointers set to address 0 or nullptr) are particularly useful when dealing with dynamic memory allocation. In the context of dynamic memory allocation, a null pointer basically says “no memory has been allocated to this pointer”. This allows us to do things like conditionally allocate memory:

Deleting a null pointer has no effect. Thus, there is no need for the following:

Instead, you can just write:

If ptr is non-null, the dynamically allocated variable will be deleted. If it is null, nothing will happen.

Memory leaks

Dynamically allocated memory effectively has no scope. That is, it stays allocated until it is explicitly deallocated or until the program ends (and the operating system cleans it up, assuming your operating system does that). However, the pointers used to hold dynamically allocated memory addresses follow the scoping rules of normal variables. This mismatch can create interesting problems.

Consider the following function:

This function allocates an integer dynamically, but never frees it using delete. Because pointers follow all of the same rules as normal variables, when the function ends, ptr will go out of scope. Because ptr is the only variable holding the address of the dynamically allocated integer, when ptr is destroyed there are no more references to the dynamically allocated memory. This means the program has now “lost” the address of the dynamically allocated memory. As a result, this dynamically allocated integer can not be deleted.

This is called a memory leak. Memory leaks happen when your program loses the address of some bit of dynamically allocated memory before giving it back to the operating system. When this happens, your program can’t delete the dynamically allocated memory, because it no longer knows where it is. The operating system also can’t use this memory, because that memory is considered to be still in use by your program.

Memory leaks eat up free memory while the program is running, making less memory available not only to this program, but to other programs as well. Programs with severe memory leak problems can eat all the available memory, causing the entire machine to run slowly or even crash. Only after your program terminates is the operating system able to clean up and “reclaim” all leaked memory.

Although memory leaks can result from a pointer going out of scope, there are other ways that memory leaks can result. For example, a memory leak can occur if a pointer holding the address of the dynamically allocated memory is assigned another value:

This can be fixed by deleting the pointer before reassigning it:

Relatedly, it is also possible to get a memory leak via double-allocation:

The address returned from the second allocation overwrites the address of the first allocation. Consequently, the first allocation becomes a memory leak!

Similarly, this can be avoided by ensuring you delete the pointer before reassigning.

Conclusion

Operators new and delete allow us to dynamically allocate single variables for our programs.

Dynamically allocated memory has no scope and will stay allocated until you deallocate it or the program terminates.

Be careful not to dereference dangling or null pointers.

In the next lesson, we’ll take a look at using new and delete to allocate and delete arrays.

6.9a -- Dynamically allocating arrays
Index
6.8b -- C-style string symbolic constants

210 comments to 6.9 — Dynamic memory allocation with new and delete

  • Tore

    So could I just clarify… should dynamic memory like this be used all the time? ie., should I never use static/automatic allocation again? Not sure on the best practice.

    • Alex

      If you have a choice, you should always favor static/automatic allocation. You should only use dynamic allocation when you can’t use static/automatic allocation (e.g. you need an array whose size isn’t known until runtime).

  • nikos-13

    What is "exit(1)" ?

    • Alex

      See http://www.learncpp.com/cpp-tutorial/712-handling-errors-assert-cerr-exit-and-exceptions/

      Since I hadn’t covered that yet and it wasn’t critical to the example, I’ve removed it from the example.

  • James

    It’s probably a good idea to say and give an example of deleting a pointer before it is reassigned or reallocated, in order to prevent memory leaks.

  • Dani

    Hello Alex…
    i have a question.
    can we access value of variable inside a memory adress (for example 0x6729cb) from another application ?

    • Alex

      In general, no, not directly. There are ways around this if your application has administrative/system privileges via OS-specific functionality.

      If you want two applications to communicate, there are other more formal and more secure ways to do this (read up on interprocess communication).

      • Dani

        Thanks Alex for your explanation.it help me a lot…
        i have a question again about memory usage.i see that variable of string has 4 byte per variable,but it can hold 10 letters even more…How can 4 byte of memory hold over 10 letters ?Thanks…

        • Alex

          sizeof() only reports non-dynamic memory because sizeof() is resolved by the compiler, and the compiler doesn’t know about dynamic memory. Strings typically allocate space dynamically because the length of the string has to be adjustable. So when you sizeof() a string, you’re just getting the size of the pointer pointing to the memory holding the string, plus any other bits of overhead.

  • Zangin

    Thanks for the tutorial.

    For the uniform initialization you mentioned
    int *ptr2 = new int { 6 }; // use uniform initialization
    perhaps one can use a shorter form, like this:
    int *ptr2 { new int { 6 } };

  • Nurlan

    Hello,
    Alex
    I have questions about memory leak.I really did not get this sentences as you said
    “This function allocates an integer dynamically, but never frees it using delete”
    1.Why we can’t  deallocate  using delete operator?
    What I understood is we always have to use always delete operator and null pointer(to avoid dangling pointer) when we have no need data from the dynamically allocated memory, otherwise memory leak occur.
    These are examples are given by you. So if we use delete operator and set pointer to a null pointer , I think , we don’t face this memory leak issues
    Your examples:
    Memory leaks can also result if the pointer holding the address of the dynamically allocated memory is reassigned to another value:

    int value = 5;
    int *ptr = new int; // allocate memory
    ptr = &value; // old address lost, memory leak results

    It is also possible to get a memory leak via double-allocation:

    int *ptr = new int;
    ptr = new int; // old address lost, memory leak results

    These examples having memory leak. So if we use delete operator, there is no problem of memory leak. Null pointer only used only when we don’t have to reassign on pointer.  Am I right?

    2.I didn’t understand about destroying the pointer in below sentences as well.  
    “when ptr is destroyed there are no more references to the dynamically allocated memory.”

    But my understanding is when pointer is going out of scope  then the pointer is destroyed. I am right?
    Please correct me if I am wrong.
    3. Can you tell me the steps of avoiding to have memory leak? If i am wrong on above statements.
    Thanks in advance.

    • Alex

      1) You can (and should) delete allocated memory using delete. The sample function doesn’t (for illustrative purposes), which is an error.

      In the examples you quoted, if you were to delete the allocated memory _before_ reassigning the pointer, you could prevent the memory leak. The examples don’t do this, to show various ways that memory can be leaked if you’re not careful.

      2) The pointer is destroyed when it goes out of scope, but the memory is not deallocated. And since you no longer have a pointer to the allocated memory, you have no way to ever deallocate the memory (until the application exits and cleans up).

      3) There are many ways to have memory leaks, and I can’t advise you on how to fix them all. One good way to avoid memory leaks is to not use dynamic memory at all. 🙂 Another good way is to use classes that implement RAII. We discuss this in chapter 8. Another way is to use smart pointer classes (such as std::unique_ptr), which we’ll cover in chapter 15.

  • JAYDEEP

    Hello,

    What is the difference between direct and uniform initialization?

    Thank you for the simple and robust tutorials.

  • Bagas

    I don’t understand why we should set a dangling pointer as a nullpointer to prevent crash. . The program still crash when we dereferencing a nullpointer, so it’s still not safe. Please enlight me

    • Alex

      Because you can check if a pointer is null before trying to dereference it.

      There’s no way to check if a non-null pointer is pointing to valid memory, so assigning invalid pointers to null gives us a way to make sure we don’t do things like try to dereference them.

  • Dan

    I want to see what the address displays after assigning value 25 to allocated address below. I compiled it and printed the result.

       *crazy = 25;   // store value at allocated memory

       cout << crazy << endl;     ---> it prints 0x9643a10 as 28 bits address
       cout << &crazy << endl;    ---> it prints 0xbfe56b6c as 32 bits address

    Using pointer crazy and &crazy to display for the address should appear the same but it shows different addresses?

    • Alex

      I see what you’re asking now -- I missed that 0x9643a10 only had 7 digits, not 8. I think what’s likely happening here is that std::cout is stripping the leading zeros in the address, so 0x9643a10 is actually 0x09643a10.

  • Dan

    I ran this trivial program and printed the result here.
    I seem to fail understand the reason why the address appears 28 bits for obtaining memory from the operating system for the dynamic memory allocation.

      1 #include <iostream>
      2 using namespace std;
      3
      4 int main()
      5 {
      6    int *crazy(0);
      7
      8    cout << crazy <<  endl;
      9    cout << &crazy << endl;
    10    cout << *(&crazy) << endl;
    11
    12    crazy = new int;  //   obtain memory for the  variable crazy
    13
    14    *crazy = 25;   // store value  
    15
    16    cout << crazy << endl;
    17    cout << &crazy << endl;
    18
    19    cout << "see what what happens before using delete(): " << *crazy << endl;
    20    cout << &crazy << endl;
    21
    22
    23    delete crazy;
    24
    25    cout << "see what happens after using delete(): " << *crazy << endl;
    26
    27    return 0;
    28 }
    ======================================================
    Outupt from the program above:

    0
    0xbfe56b6c
    0
    0x9643a10  ==============> ????? 28 bits not 32 bits.
    0xbfe56b6c
    see what what happens before using delete(): 25
    0xbfe56b6c
    see what happens after using delete(): 0

  • Norton Verde

    Very good and clear explanations revealing a deep and trustable knowledge. Congratulations .I’ll be back frequently !

  • Ivar

    Btw, I need to #include <new> to get access to std::nothrow (found out from the c++ reference). Maybe you should add that, unless it’s specific to me (I’m using gcc).
    Thanks for a great tutorial!

  • Ivar

    Does new differ from just using malloc()? Or is it just a convenience to have it as a keyword? (I’m asking because if you don’t want an exception thrown, writing

    feels more complicated than just doing

    . If you do want an exception at failure new is clearly better!)

    • Alex

      Yes, new is different than malloc(). One key difference is that new will call constructors of classes, whereas malloc will not. In effect, malloc is not class-aware. New is also more type-safe.

      In C++, you should never user malloc(). Always use new.

      • Ivar

        Ah ok, I didn’t think of that. That does make it a lot easier and safer to use with classes.

        If you have time, could you elaborate on how new is more type-safe? (Just curious, you’ve already convinced me to use it..)

        • Alex

          In C++, malloc() returns a void* and you must cast this to whatever type you intended. This leaves a lot of room for errors/silliness. new on the other hand ensures proper type-checking:

  • Akub

    Hi Alex,

    While experimenting with pointers in Visual Studio, I’ve come across something a bit worrying. Maybe you could explain what’s happening and let me know if it’s a bug in the compiler. The following program executes just fine on my computer, but I’m not sure if it’s safe to run.

    For some reason, it lets me assign to *otherPtr, even though the memory is deallocated. Bizarrely, the same is not true for *ptr in the commented out line.

    Also, thanks a lot for your tutorial! It has helped me a great deal.

    • Alex

      Ensuring you don’t access dangling pointers is the responsibility of the programmer, not the compiler. So the fact that you are able to assign to *otherPtr isn’t a bug in the compiler (but it will cause undefined behavior if you try to run the program). Rather, the fact that your Visual Studio appears to be preventing you from compiling “*ptr = 5” just after deleting ptr is an unexpected nicety.

      • Akub

        I see. But since I am allowed to access and change the values pointed to by dangling pointers, does that mean my program could directly interfere with other programs and/or the operating system?

  • Punched Fortran

    Other typos:
    "Pointers that are pointing to deallocated memory are called dangling pointer" should probably read "Pointers that are pointing to deallocated memory are called dangling pointers" (make second "pointers" plural).
    "Operator new and delete allow us to dynamically allocate …" should probably read "Operators new and delete allow us to dynamically allocate …" (make "Operators" plural).  
    (Sorry -- should have read the whole article first.)  Thanks again for all your work!

  • Punched Fortran

    Typo, " … overflow the record array and watching something bad happen." should probably read " … overflow the record array and watch something bad happen."
    Thanks for the tutorial!

  • Alf

    Hi Alex,
    Thanks for your tutorial.
    Do you know how to avoid double-allocation problem you mentioned in the last part? I use a class with a deque pointer member. I may create many deques and let that pointer point to them according to the change of input.

    • Alex

      The easiest way to avoid double allocation is to always make sure you always delete your variables before reallocating.

      You can also use std::unique_ptr from the C++ standard library to help manage the lifetime of your pointers. I’m intending to write lesson on std::unique_ptr soon.

  • Nyap

    How can you see the size of the heap on your system

    • Nyap

      also, if you don’t use the "delete" operator to explicitly deallocate a dynamically allocated variable, will that memory be unusable by other programs until you reboot your pc/phone/whatever

    • Alex

      It varies by OS, as well as how much physical memory you have, how much hard drive swap space you have, and how much memory is being used. I’m not aware of any easy way to see how much memory is available on the heap.

  • J3ANP3T3R

    if anyone could help im a bit confused:

    "Note that deleting a pointer that is not pointing to dynamically allocated memory may cause bad things to happen."

    but

    "If ptr is non-null, the dynamically allocated variable will be deleted. If it is null, nothing will happen."

    shouldn’t we need to check if the pointer is not null before we delete it ? or else we get "bad things to happen" ?

    • Alex

      Nope. If your pointer _ever_ points to non-dynamically allocated memory, you’ve already screwed up somewhere and your program is doomed. So let’s assume that can’t happen, because you’d never do that. That means that your pointer is either pointing to dynamically allocated memory, or it’s pointing to null. If it’s pointing to dynamically allocated memory, and you delete it, then great, the memory gets deallocated. If it’s pointing to null and you delete it, then nothing happens, which is fine. In either case, a pre-check for non-null doesn’t provide any additional value.

      In the case where you ARE pointing to non-dynamically allocated memory, or some other garbage value, a null check won’t help you anyway -- the pointer is non-null so it will pass, and then you’ll try and delete it, and your program will probably crash.

  • Elpidius

    Hi Alex,

    I’m confused with something.

    You wrote:
    "Your computer has memory (probably lots of it) that is available for applications to use. When you run an application, your operating system loads the application into some of that memory. Your application reserves some additional memory for normal operations (keeping track of which functions were called, creating and destroying global and local variables, etc…)."

    Does the application reserve some additional memory from RAM without permission from the Operating System? Or in the third quoted sentence were you meant to say: "From this allocated memory your application reserves some of that memory for normal operations…"

    • Alex

      I rewrote the text in question to (hopefully) be more precise and more understandable. The OS handles the loading of the application into memory and setting up all of the pointers that are used by the application to access the different areas of memory it requires for operation.

  • Shiva

    Hey Alex,

    A few suggestions:

    > The new operator returns the address of the variable that has been allocated.
    I believe new returns ‘a pointer containing the address of the variable’ that has been allocated, rather than the address as literal, just like the & operator? If that’s so, you’d better modify the wording to be clear.

    > Without a pointer to hold the memory address of the memory that was just allocated, …
    ‘memory address of the memory’ feels a bit awkward. ‘address of the memory’ would have sufficed. 😀

    Last thing: I read elsewhere that the new operator can also do initialisation of the dynamically allocated memory, like:

    If you haven’t already mentioned it somewhere, isn’t this a point worth including?

    Anyway great lesson, once again. Thanks as always! 🙂

  • cei

    There is a typo: one "allocated" is missing a ‘t’.

  • dex

    Hi Alex,

    In the lesson’s example:

    "Deleting a null pointer has no effect. Thus, there is no need for the following:"

    be

    if we want the if condition evaluates to true and then delete the null pointer?

    Although, as you said it could be done without the condition statement. I am just confused with the logic of the condition.

    Thanks.

    • Kodnot

      The first if statement would be used if we wanted to delete the pointer if it WAS NOT a null pointer. But because deleting a null pointer has no effect (aka it won’t cause problems), there is no need to do so.
      In other words, we want the If to evaluate to true if the pointer does not point to null, not vice versa ^^

    • Alex

      Deleting a null pointer does nothing (it is not harmful). Therefore, there is no need to say:

      Instead we can just say

      Because if ptr is a null pointer, delete ptr will do nothing anyway. So there’s no need to guard against deleting the null pointer (with an if statement).

      This code:

      is completely useless. If ptr is a null pointer, it will delete the null pointer, which does nothing. If ptr is not a null pointer, it will skip the delete statement, doing nothing.

      • dex

        Hi Alex, Kodnot,

        Thanks for clarifying it. actually, I was confused with the intent of this statement:

        "Deleting a null pointer has no effect. Thus, there is no need for the following:"

        Instead we can just say

        I interpreted it the other way around that is why I was then confused with the logic of the code.

  • Aditya

    Firstly great tutorial.Excellent work.

    In dynamically allocating single variables you have done

    however *ptr is a pointer.
    So how can we assign it a value?

    In chapter 6.7 you have clearly stated that we must assign address

    So which is correct or are both of them correct? I am totally unable to get my mind around this.
    Thanks in advance

    • Alex

      In this context, * is acting as a dereference, so *ptr means “the value at the address of ptr”. So we’re assigning the integer value 7 to the value at the address of ptr.

      This would be an invalid syntax (unless ptr is a pointer to a pointer).

      What I actually said was this:

      In this case, * means ptr is a pointer.

      The difference here is in context: * used in a variable declaration means “pointer”, * used otherwise means “dereference”.

  • Phuong H Tran

    I like your profile pic, Alex. the cat’s face is hilarious. Haha.

  • George

    Dear Alex I might be a bit confused about pointers!
    in this lesson, you put a value to an allocated memory like this:

    int *ptr = new int; // allocate memory and put address in ptr
    *ptr = 5; // put a value in that memory

    I allocated memory for an array but without the asterisk:

        int *array = NULL;
        array = new int[1000000];
    How do you explain this?
    How can I do the same without specifying the array’s size?

    • Alex

      Could be rewritten as:

      Which you can see is analogous to how we allocated memory for a single int.

      When we dynamically allocate memory (whether for a single value or an array), the operating system returns an address to the allocated memory. We store that address in variable ptr (or array, in the array case).
      Now, to access that memory, we need to dereference the pointer. For a single value, we use operator*: e.g. *ptr = 5; For arrays, we can use either operator* (to access the first element of the array), e.g. *array = 5; or the subscript operator[], e.g. array[3] = 5.

      Does that make sense? If not, where are you still confused?

  • Sean Kelly

    In the lesson should:

    Be

    Unless this is a way to handle exceptions?

  • Roee Sefi

    Hi Alex
    As far as i know,  the c++ standard says that when new operator fails, it throws std::bad_alloc exception (unless being told not to with "no throw").
    The returned null pointer was just De-Facto outcome from old unstandardized compilers

  • Georgios Leandros Κυριαζης

    I need some clarification in the nullptr. is it wise to initialize pointers using the nullptr? for example is wise/ok/right/wrong to have a contstructor like bellow

    or would it be better to do like this

    is there a meaningful difference between the two?

    Or should I only use the nullptr to deallocate memory.

    • Alex

      nullptr is the C++11 replacement for using 0 as a null pointer. Using nullptr is slightly better than using 0, as it makes your intent clearer and this can help avoid ambiguities in certain cases.

  • EML

    Hi Alex,

    Thanks for this great tutorial.

    I am trying to understand the delete operator closer to the system level.
    By the description it sounds like all delete should do is flip some bit flag that changes how that memory location is handled and the address stored in ptr should be unaffected by the delete operator.
    But when I run…

    the output on my machine is :
    …00454FC0
    …00008123

    After passing ptr as the argument to the delete operator it now holds a different memory address. I am concerned that I am missing something… I understand this doesn’t affect implementation since the original address contains garbage now but where is this new address coming from?

    Thanks for your help!

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter