6.9a — Dynamically allocating arrays

In addition to dynamically allocating single values, we can also dynamically allocate arrays of variables. Unlike a fixed array, where the array size must be fixed at compile time, dynamically allocating an array allows us to choose an array length at runtime.

To allocate an array dynamically, we use the array form of new and delete (often called new[] and delete[]):

Because we are allocating an array, C++ knows that it should use the array version of new instead of the scalar version of new. Essentially, the new[] operator is called, even though the [] isn’t placed next to the new keyword.

Note that because this memory is allocated from a different place than the memory used for fixed arrays, the size of the array can be quite large. You can run the program above and allocate an array of length 1,000,000 (or probably even 100,000,000) without issue. Try it! Because of this, programs that need to allocate a lot of memory in C++ typically do so dynamically.

Dynamically deleting arrays

When deleting a dynamically allocated array, we have to use the array version of delete, which is delete[].

This tells the CPU that it needs to clean up multiple variables instead of a single variable. One of the most common mistakes that new programmers make when dealing with dynamic memory allocation is to use delete instead of delete[] when deleting a dynamically allocated array. Using the scalar version of delete on an array will result in undefined behavior, such as data corruption, memory leaks, crashes, or other problems.

One often asked question of array delete[] is, “How does array delete know how much memory to delete?” The answer is that array new[] keeps track of how much memory was allocated to a variable, so that array delete[] can delete the proper amount. Unfortunately, this size/length isn’t accessible to the programmer.

Dynamic arrays are almost identical to fixed arrays

In lesson 6.8 -- Pointers and arrays, you learned that a fixed array holds the memory address of the first array element. You also learned that a fixed array can decay into a pointer that points to the first element of the array. In this decayed form, the length of the fixed array is not available (and therefore neither is the size of the array via sizeof()), but otherwise there is little difference.

A dynamic array starts its life as a pointer that points to the first element of the array. Consequently, it has the same limitations in that it doesn’t know its length or size. A dynamic array functions identically to a decayed fixed array, with the exception that the programmer is responsible for deallocating the dynamic array via the delete[] keyword.

Initializing dynamically allocated arrays

If you want to initialize a dynamically allocated array to 0, the syntax is quite simple:

Prior to C++11, there was no easy way to initialize a dynamic array to a non-zero value (initializer lists only worked for fixed arrays). This means you had to loop through the array and assign element values explicitly.

Super annoying!

However, starting with C++11, it’s now possible to initialize dynamic arrays using initializer lists!

Note that this syntax has no operator= between the array length and the initializer list.

For consistency, in C++11, fixed arrays can also be initialized using uniform initialization:

One caveat, in C++11 you can not initialize a dynamically allocated char array from a C-style string:

If you have a need to do this, dynamically allocate a std::string instead (or allocate your char array and then strcpy the string in).

Also note that dynamic arrays must be declared with an explicit length:

Resizing arrays

Dynamically allocating an array allows you to set the array length at the time of allocation. However, C++ does not provide a built-in way to resize an array that has already been allocated. It is possible to work around this limitation by dynamically allocating a new array, copying the elements over, and deleting the old array. However, this is error prone, especially when the element type is a class (which have special rules governing how they are created).

Consequently, we recommend avoiding doing this yourself.

Fortunately, if you need this capability, C++ provides a resizable array as part of the standard library called std::vector. We’ll introduce std::vector shortly.


1) Write a program that:
* Asks the user how many names they wish to enter.
* Asks the user to enter each name.
* Calls a function to sort the names (modify the selection sort code from lesson 6.4 -- Sorting an array using selection sort)
* Prints the sorted list of names.

Hint: Use a dynamic array of std::string to hold the names.
Hint: std::string supports comparing strings via the comparison operators < and >

Your output should match this:

How many names would you like to enter? 5
Enter name #1: Jason
Enter name #2: Mark
Enter name #3: Alex
Enter name #4: Chris
Enter name #5: John

Here is your sorted list:
Name #1: Alex
Name #2: Chris
Name #3: Jason
Name #4: John
Name #5: Mark

Quiz solutions

1) Show Solution

6.10 -- Pointers and const
6.9 -- Dynamic memory allocation with new and delete

287 comments to 6.9a — Dynamically allocating arrays

  • Chetan

    my program get crash

  • Matt

    Here's what I came up with for this lesson's quiz...admittedly I found it to be one of the most challenging so far (not conceptually, but syntactically).  In my head I'm thinking, "I want to pass the (pointer to the names array) to the function so the function can do something with the array," but then I would spin my wheels for minutes each time trying to remember when to and not to use the *.  This was an outstanding exercise though - I'm glad you decided to make a list of names and not numbers which was an extra little curve ball that made me pause and think for a second (in terms of the std::string* return value from the getNames function) and further illustrated the power of std::string.

    Thanks for yet another awesome lesson, I have a feeling I'm going to want to review arrays again considering how relatively difficult I found this quiz.

    • nascardriver

      Hi Matt!

      > I want to pass the (pointer to the names array) to the function so the function can do something with the array
      Nice use of brackets

      > I would spin my wheels for minutes each time trying to remember when to and not to use the *
      Completely normal, it can take a while to get used to pointers and references

      > Why is it not required to use std::getline?
      std::cin can extract strings. What it doesn't do is extract spaces. If you entered a name with a space in it you'd only get the part before the space. std::getline gets everything.

      To your code:
      Good old 32767 std::numeric_limits<std::streamsize>::max() switcheroo
      Line 33:

      • Matt

        >Good old 32767 std::numeric_limits<std::streamsize>::max() switcheroo
        Touche, I've been taking the lazy way.  Next time I need a std::cin.ignore I'll try to remember that parameter ha!

  • J

    Hello, thank you for these lessons. I've learned a lot already. I managed to solve this lesson's quiz, but when I tried switching to the bubble sort algorithm from previous lessons, it compiled without issue then crashed during the sort function.  Please can anyone spot the problem with this function?

    • nascardriver

      Hi J!

      Example for @length = 6
      The highest value of @nextHighest is (@length - 1) = 5.
      The highest value of @index is @nextHighest = 5.
      The highest value of (@index + 1) in Line 12 is 6.
      You're trying to access an invalid index.

      • J

        Thanks nascardriver, I understand now. I think I must have got really (un)lucky to get no errors while testing the sort function with ints. I switched the inner loop's <= to < and it works just fine now.

  • Silviu

    Can you explain "i+1" that is used in the quiz ? Selection sort , sorts numbers from 0 to lets say 100 and here sorts them alphabetical, what i don't understand - how it does know which is A,b,c,d and so on... In ascii code i know the characters are represented by some numbers like A=65. Here i don't know how it compares it , can you explain ? Thank you.

    • nascardriver

      Hi Silviu!

      It adds 1 to @i before printing it (Without actually modifying @i).


      • Silviu

        Thank you, now i understand instead of showing 0, it shows 1 in the ouput. I edited my comment, can you explain the rest ? thank you

        • nascardriver

          Alex' solution, line 17

          std::string has a < operator which uses std::string::compare to perform a lexicographical (alphabetical) comparison of two strings.

  • Coded a few lines on my own, but I have to admit that most of this is the author's work. I'm a little concerned with line 52 though. All the code runs fine, but I'm not sure if I got the names array parameter fixed the right way in the function. I was just exploring, and luckily it works. Is it wrong? I appreciate any and all comments/suggestions. Thanks.

    • nascardriver

      Hi Chandler!

      Line 52 is the correct way of doing it. Having a separate function to print out the array is also better than doing it in main as Alex did in his solution. In lesson 6.10 you'll learn more about the 'const' keyword, it would be used in this case.

  • Denis

    Lately I have been trying to improve my coding by practicing on basic competition sites and I keep running in to the same issue I do not understand. Many of the successful examples listed for problems look like this:

    #include <iostream>
    using namespace std;
    int main() {
        int n,k,count;
        int a[n][5];
        for(int i=0;i<n;++i)

    This does not compile on my IDE and it seems to violate the necessity of run-time definition of the size of the array (but is very common practice). Can you explain to me what I am missing/how they are working around the run-time definition issue?

    • nascardriver

      Hi Denis!

      I don't know if that is legal c++ (If your compiler says no it might not be), anyway it shouldn't be done.
      When declaring an array like that some compilers will create the array on the stack as opposed to on the heap when using the 'new' keyword. The stack is faster than the heap but limited in size, arrays are big, they shouldn't be on the stack.
      The code you posted is bad. You can continue learning on the side providing this code but you shouldn't do as they do.

      • Alex

        It's not legal in C++. This is legal C99 though, and this program looks an awful lot like a C99 program (variables declared up top, use of scanf, and of course the non-constexpr array sizes).

  • Anderson

    Hi everybody, I just finished mine, is this the right way to initialize an array of strings?

    This is the entire code, critics and feedbacks are welcome:

    • nascardriver

      Hi Anderson!

      > is this the right way to initialize an array of strings?
      I guess so, I can't tell for sure.

      I modified your code and added comments. I also re-formatted to source, do as you wish as long as you can read it.
      EDIT: The edit function broke backslashes, imagine they were there.

      • Anderson

        Thanks for the feedback! About the (!std::getline(std::cin, returnString)), yes you're right, there is no false possibility here, earlier I was reading about file reading and mixed things up, hehe...
        About the std::string *namesArray{ new std::string[ammountNames]{} };, how would you initialize it? Anyway I initialize the array, all the strings seems to be intialized to "", but I'm not sure if this is a undefined behavior or dynamic arrays get initialized automatically...

  • Saumitra Kulkarni

    Hi Alex

    This works just fine even if we use run time constant.Why is it so?(Shouldn’t Array length be compile time cont?)
    And if this usually works, is there a need to dynamically allocate memory for array if we want variable length of the array?

    • nascardriver

      Hi Saumitra!

      You missed a semicolon in line 6.

      > Why is it so?(Shouldn’t Array length be compile time cont?)
      Creating an array your way will create the array on the stack as opposed to new which will create the array on the heap (Lesson 7.9). The stack is limited in size whereas the head has no limits (At some point your RAM is full though). This can be problematic with larger data types.

      > And if this usually works
      I'm not sure if all compilers support this, let's wait for Alex.

      > is there a need to dynamically allocate memory for array
      As I said above, the stack is limited in size, using new to create an array is preferred.

  • david

    1st) I allocated the array in a separate function
    but in this case is main{} the proper place for delete[] ?

    2nd) is there away to put numNames in getNames()?

    • nascardriver

      Hi David!

      1st) I allocated the array in a separate function but in this case is main{} the proper place for delete[] ?
      You can do it like that, this however has the disadvantage that you'll have to remember that @getNames allocated memory which needs manual deletion. A better approach would be to allocate the array in main and pass it to @getNames. If you want to keep it as it is I suggest you adding a comment above @getNames to make clear that the returned array needs to be deleted by the caller.

      2nd) is there away to put numNames in getNames()?
      There are several ways, so far, you know about pointers. Reading the amount of names in @getNames is good practice.

      Add some whitespace to your code for readability.

  • Ivan

    Hi Alex,

    If pointer to array doesn't know how large the array is, how delete[] knows how many bytes to delete once called on pointer?

    • nascardriver

      Hi Ivan!
      This varies from compiler to compiler. There'll be a block of memory describing how much memory has been allocated so delete, delete[], free, etc. know how much memory to free.
      This block is not meant to be accessed by the user, if you want to keep track of an arrays size you'll need to do so on your own.

  • merocom

    • nascardriver

      Hi merocom!

      Congratulations on solving the quiz!

      Line 5: Don't use "using namespace"
      Line 10, 15: Initialize your variables
      Line 12: You're allowing the user to enter negative numbers, this will cause a crash. The quiz didn't ask you to validate the input but you should be careful whenever the user controls the program.
      Line 15: Unused variable @name
      Line 16, 25: Bad iterator name, i is preferred for ints.
      Line 16, 25: Use ++x instead of x++ for pure incrementations
      Line 22, 29: You don't need that empty string, std::cout << std::endl; does the same
      Line 37, 38: Inconsistent use of curly braces, use curly braces.
      @main: Missing return statement.

  • Max

    Hey Alex,

    Tried searching for this answer but couldn't find it. At the end of the quiz solution you have the following:

    Which is directly followed by main() finishing, meaning the memory is returned anyways. Two questions:

    1) Why the need to delete it right before?

    2) Any reason you wrote "names = nullptr;" with a tab under the previous line, instead of without any tab?

    Thank you in advance, and thanks for the tutorials!

    • nascardriver

      Hi Max!

      Always manage your memory in your program!
      Does Windows clean up after you? Yes it does.
      Do other OSs clean up after you? I don't know, mine doesn't, at least not properly.
      If you allocate memory then you're the one responsible for freeing it.

      That's uncommon, he didn't have it like that in the code above, you'll have to wait for Alex.

    • Alex

      1) It's good practice to clean up your messes. If you get in the habit now, then you'll remember to clean up your messes when it actually matters.
      2) No, it was just a formatting error. Whitespace doesn't matter in C++. Also, I've removed this line altogether since it's unnecessary (since the variable is going out of scope immediately after).

  • Vili Sinervä

    Hi, I just completed this quiz. I wanted to put everything into their own functions. Is this a good or bad habit to get into? Also is the way I had the functions change the array directly fine? Are there any other things you think could be improved upon? Thanks!

    • nascardriver

      Hi Vili!
      Good job solving the quiz!

      "I wanted to put everything into their own functions. Is this a good or bad habit to get into?"
      That's good, it makes maintaining code easier and improves reusability.

      "Also is the way I had the functions change the array directly fine?"
      It is, as long as you pass the array size alongside the array.

      "Are there any other things you think could be improved upon?"


      Those are wrong quotation mark things, I don't know what happened there, it should be '\n'. Also, you're calling that function rather often, every time with the same parameters, write a function for it. While you're at it use std::numeric_limits<std::streamsize>::max() instead of 32767, this value is guaranteed to wait until delim is found, 32767 doesn't.
      Lines 8, 31, 43: Initialize your variables
      Lines 69, 70 and others: Inconsistent use of initializations, use curly braces.
      Lines 61, 69: Inconsistent spacing around curly braces, use spaces around value.
      Line 63: Double semicolon.
      In @getNames: Unnecessary variable @enteredName, you can use std::cin >> names[name];
      In every for-loop except 47: Badly names iterator.
      @getNumberOfNames allows negative inputs, causing a crash.
      Line 20: Don't have an empty line there, it's confusing.
      Every @nOfNames: const isn't usually used for parameters copied by value, you can keep it to prevent attempts to assign a value to it.

      Other than that it looks good. I'm being picky here to prevent you from getting used to bad habits, keep going.

    • Alex

      Using functions to separate discrete steps is a great practice, and you've done a good job with this. Keep it up!

      Also having functions change the value of the argument is okay, so long as it's obvious that it is going to do so. For example, a sort function is clearly going to change the order of the elements in an array. A print function had better not. You can use const to help enforce/communicate this.

      Nascardriver's feedback is great for the more tactical suggestions. Keep up the good work Nascardriver.

  • Jeffery

    I know it is unrelated to the lesson, but while I was experimenting with my program for the quiz, I was havin a problem with std::getline. It would not ask for user input in the first iteration of my for loop asking for names, but worked fine for the rest. This was when I entered 5. I later added     std::cin.ignore(32767, 'n'); after the place where it asked for the number of names and it seemed to work fine, showing that there were too many inputs(at least I think). Do you mind looking over mycode to see why this may occur.

    void Sort(std::string *if, int length)
        for (int startIndex = 0; startIndex < length - 1; ++startIndex)

            int smallestIndex = startIndex;

            for (int currentIndex = startIndex + 1; currentIndex < length; ++currentIndex)
                if (if[currentIndex] < if[smallestIndex])
                    smallestIndex = currentIndex;

            std::swap(if[startIndex], if[smallestIndex]);

    int main()
        int nameLength;

            std::cout << "How many names would you like to enter? ";
            std::cin >> nameLength;
        //    std::cin.ignore(32767, 'n'); adding this makes it work as intended
        std::string *ptr = new std::string[nameLength] ();
        for (int i{ 0 }; i < nameLength; ++i)
            std::cout << "Enter name #" << i + 1 << ": ";
            std::getline(std::cin, ptr[i]);

        Sort(ptr, nameLength);
        for (int i{ 0 }; i < nameLength; ++i)
            std::cout << ptr[i];
    delete[] array;
    array = nullptr;

    • nascardriver

      Hi Jeffery!
      Whenever you input something through std::cin it will be stored in a buffer internally.
      When the user inputs nameLength a '\n' character will be in that buffer, because the user pressed enter (which is '\n' or "\r\n").
      Now, when you call std::getline it will see that there's a '\n' in the buffer and it will do it's thing, because it thinks the line is over.
      To fix this you can add this line

      This will ignore all input until to next '\n', which is the '\n' you received via std::cin.
      Note: std::numeric_limits<streamsize>::max() might not be available with old compilers or old settings, if you encounter problems you can replace it with a large number.

      Also, in your Sort function you have a variable named "if", don't do this.

    • Alex

      When you ask how many names to enter, your input captures both the number entered and the newline character. Then when you call std::getline, it finds the newline character still in the input stream, and interprets that as an empty string. Calling std::cin.ignore() flushes the newline out of the stream so your code works as expected.

      I talk about this problem in lesson

  • Ben

    Hi, I've just finished the quiz and was hoping for a little feedback 🙂

    The code works fine and does what it should but it does differ from yours in the solution and was wondering if it would be an issue for optimisation etc. One question I do have, when checking the solution after completing the quiz I realised that initially I had forgot to include <utility> but the std::swap still seemed to work, why would this be the case?


    • Alex

      Your code could use some comments defining the different sections of main helping clarify what the different sections do (user input, sort, print list). There's also no need to set array to nullptr at the end of the function, since array will get destroyed just after that point.

      It's possible one of the other headers you include included utility itself. You should still include it.

  • Bryan

    Hello Alex,

    While I understand how to make a dynamic array, it is not described how to allocate and use a multi-dimensional array.

    If I would make an array like:

    How does the pointer returned from the array work?
    Does it return multiple pointers for each of the starting elements per dimension?

    And if for example I would want to iterate through a multi-dimensional array using:

    how would I iterate that it goes to the next dimension of the array?
    with + length ? or using multiple pointers?

    I'm sorry for the multiple questions, I hope you are able to answer them!

    Thank you very much for your tutorials I really consider them the best around!

  • Mattermonkey

    If pointers to arrays don't know how long the array is, how does delete[] know how much memory to deallocate?

    • Alex

      When you allocate dynamic memory using new[], the size of the allocated memory is stored, so that when delete[] is called, the proper amount can be deallocated. Unfortunately, this size isn't accessible to the programmer.


    You said b4 that we need to use this, so our program doesn't skip over after asking for a number then a string, but yours didn't skip at all.

    Here's my code: What do you think? Thank you.

  • Kushagra

    Why can't we use std::getline to get names?
    what about getting sirnames  with std::cin?
    didn't it put the sirname to the next std::cin ?

    • Alex

      > Why can’t we use std::getline to get names?

      You can, like this:

      > what about getting sirnames with std::cin?

      std::cin and operator<< break on whitespace. So you'd have to keep reading until you hit a newline and concatenate the results. If you want to do this, just use std::getline.

      • Kushagra

        using std::getline is causing run time error.
        name 1 is printed. without asking anything it also prints name 2 , then it asks about entering name

        • Alex

          Can you post your code snippet that's not working?

          • Kushagra

            Your snippet is doing the same problem.

            #include <iostream>
            #include <string>
            #include <algorithm>

            void sortArray(std::string *array, int length)
                // Step through each element of the array
                for (int startIndex = 0; startIndex < length; ++startIndex)
                    // smallestIndex is the index of the smallest element we've encountered so far.
                    int smallestIndex = startIndex;

                    // Look for smallest element remaining in the array (starting at startIndex+1)
                    for (int currentIndex = startIndex + 1; currentIndex < length; ++currentIndex)
                        // If the current element is smaller than our previously found smallest
                        if (array[currentIndex] < array[smallestIndex])
                            // This is the new smallest number for this iteration
                            smallestIndex = currentIndex;

                    // Swap our start element with our smallest element
                    std::swap(array[startIndex], array[smallestIndex]);

            int main()
                std::cout << "How many names would you like to enter? ";
                int length;
                std::cin >>length ;

                // Allocate an array to hold the names
                std::string *names = new std::string[length];

                // Ask user to enter all the names
                for (int i = 0; i < length; ++i)
                    std::cout << "Enter name #" << i + 1 << ": ";
                    std::getline(std::cin , names[i]);

                // Sort the array
                sortArray(names, length);

                std::cout << "\nHere is your sorted list:\n";
                // Print the sorted array
                for (int i = 0; i < length; ++i)
                    std::cout << "Name #" << i + 1 << ": " << names[i] << '\n';

                delete[] names; // don't forget to use array delete
                    names = nullptr; // use 0 if not C++11

                return 0;

            • Alex

              Oh. You need to make sure you ignore the '\n' in the stream, like this:

              Otherwise the first call to std::getline() will read the \n and treat it as an empty string input.

  • Kushagra

    Instead of this answer of quiz , can't we rearrange names just similar to arranging integers like this

    #include <iostream>
    #include <algorithm>
    #include <string>
    int main()
        std::cout << " How many names do you want to write ?" << std::endl;
        int length ;
        std::string *block = new std::string[length];
        for (int a = 0; a<length; a++)
            std::cout << " name " << (a+1) << " is : ";
            std::cin >> block[a];
        for (int g = 0; g<length; g++)
        for ( int x =0; x<(length-1); x++)
            if (block[x] >block[x+1])
            std::swap(block[x] , block[x+1]);

        std::cout << " The sorted order is " <<std::endl;
            for (int y = 0; y<length; y++)
        std::cout << "name  " << (y+1) << " is :   " << block[y] <<std::endl;
        delete[] block;
        block = nullptr;
        return 0;

  • Frodo

    How can std::cin >> names[i] be altered so that std::cin.getline() is used?

  • JRCS

    I seem to have got into the habit of putting everything in functions if I can, so this code looks quite different to your solution. It still works, so that's cool, I suppose.

    • Alex

      Yup, that's great! Your code is nicely organized. A few minor things:
      1) Using a global "using namespace std" is frowned upon
      2) You don't need to set name to 0 after deleting it (it's going to go out of scope and get destroyed immediately anyway)

  • chathura

    Oh thx for that it did help.

  • chathura

    Hi i just have a small problem with sortArray method. How does it sort the string alphabetically i'm bit confused because i understand the concept if they were numbers. please help.

  • Eric

    I have a question about the sorting function. When sorting, is it doing it by the ascii value, because i was playing around and mixing capitalization and lowercase and it appears to be arranging by those values. What would you suggest be the most optimal way to correct this? As an example run a check and convert everything to be uniformed (capitalized or all lowercased).

    • Alex

      Yes, if you're sorting characters, it will do so by ASCII value. You can fix this by converting everything in your source array to use uniform capitalization. But a better idea is to modify your sort to deal with inconsistent capitalization (so caps gets temporarily converted to lower case before the comparison happens). That way, your source array can remain unmodified.

  • Angmar

    Hi Alex, thanks for your prior helps. I have another question.

    So the

    operator returns a pointer, right? Is it possible to dereference them with the

    operator? I was trying to build a string array and each of the following fails to build:

    I'd be very grateful if you explain why 1,2, and 6 won't work

    • Alex

      When you dereference a pointer that is pointing to an array, you get the value of the first element.
      1) Doesn't work because you're trying to initialize your names array with a single value. This causes a type mismatch.
      2) Direct initialization doesn't work with arrays, which is one of the reason uniform initialization was created.
      6) This is a confusing case. string names[] defines a string array (not a string pointer). new string[count] returns a pointer. C++ won't let you convert a pointer into an array.

Leave a Comment

Put all code inside code tags: [code]your code here[/code]