9.21 — Pointers to pointers and dynamic multidimensional arrays

This lesson is optional, for advanced readers who want to learn more about C++. No future lessons build on this lesson.

A pointer to a pointer is exactly what you’d expect: a pointer that holds the address of another pointer.

Pointers to pointers

A normal pointer to an int is declared using a single asterisk:

A pointer to a pointer to an int is declared using two asterisks

A pointer to a pointer works just like a normal pointer — you can perform indirection through it to retrieve the value pointed to. And because that value is itself a pointer, you can perform indirection through it again to get to the underlying value. These indirections can be done consecutively:

The above program prints:


Note that you can not set a pointer to a pointer directly to a value:

This is because the address of operator (operator&) requires an lvalue, but &value is an rvalue.

However, a pointer to a pointer can be set to null:

Arrays of pointers

Pointers to pointers have a few uses. The most common use is to dynamically allocate an array of pointers:

This works just like a standard dynamically allocated array, except the array elements are of type “pointer to integer” instead of integer.

Two-dimensional dynamically allocated arrays

Another common use for pointers to pointers is to facilitate dynamically allocated multidimensional arrays (see 9.5 -- Multidimensional Arrays for a review of multidimensional arrays).

Unlike a two dimensional fixed array, which can easily be declared like this:

Dynamically allocating a two-dimensional array is a little more challenging. You may be tempted to try something like this:

But it won’t work.

There are two possible solutions here. If the rightmost array dimension is a compile-time constant, you can do this:

The parenthesis are required here to ensure proper precedence. In C++11 or newer, this is a good place to use automatic type deduction:

Unfortunately, this relatively simple solution doesn’t work if any non-leftmost array dimension isn’t a compile-time constant. In that case, we have to get a little more complicated. First, we allocate an array of pointers (as per above). Then we iterate through the array of pointers and allocate a dynamic array for each array element. Our dynamic two-dimensional array is a dynamic one-dimensional array of dynamic one-dimensional arrays!

We can then access our array like usual:

With this method, because each array column is dynamically allocated independently, it’s possible to make dynamically allocated two dimensional arrays that are not rectangular. For example, we can make a triangle-shaped array:

In the above example, note that array[0] is an array of length 1, array[1] is an array of length 2, etc…

Deallocating a dynamically allocated two-dimensional array using this method requires a loop as well:

Note that we delete the array in the opposite order that we created it (elements first, then the array itself). If we delete array before the array elements, then we’d have to access deallocated memory to delete the array elements. And that would result in undefined behavior.

Because allocating and deallocating two-dimensional arrays is complex and easy to mess up, it’s often easier to “flatten” a two-dimensional array (of size x by y) into a one-dimensional array of size x * y:

Simple math can then be used to convert a row and column index for a rectangular two-dimensional array into a single index for a one-dimensional array:

Passing a pointer by address

Much like we can use a pointer parameter to change the actual value of the underlying argument passed in, we can pass a pointer to a pointer to a function and use that pointer to change the value of the pointer it points to (confused yet?).

However, if we want a function to be able to modify what a pointer argument points to, this is generally better done using a reference to a pointer instead. So we won’t talk about it further here.

We’ll talk more about pass by address and pass by reference in the next chapter.

Pointer to a pointer to a pointer to…

It’s also possible to declare a pointer to a pointer to a pointer:

These can be used to dynamically allocate a three-dimensional array. However, doing so would require a loop inside a loop, and are extremely complicated to get correct.

You can even declare a pointer to a pointer to a pointer to a pointer:

Or higher, if you wish.

However, in reality these don’t see much use because it’s not often you need so much indirection.


We recommend avoiding using pointers to pointers unless no other options are available, because they’re complicated to use and potentially dangerous. It’s easy enough to perform indirection through a null or dangling pointer with normal pointers — it’s doubly easy with a pointer to a pointer since you have to do a double-indirection to get to the underlying value!

9.22 -- An introduction to std::array
9.20 -- Void pointers

137 comments to 9.21 — Pointers to pointers and dynamic multidimensional arrays

  • Anonymous

    I am thinking about going into creating games like 2d and 3d. You say that this lesson is optional. If I am creating games and things do you think I will need to know how to do this?

    btw love the site

    • I don't know why Alex said this lesson is optional. Pointers to pointers are common. You'll need them for game development.

      • Anonymous

        Ok, thanks!

      • Alex

        I said it's optional because many programs don't require them, and no future lessons build on the concept. Users can always come back and read the lesson if they have a specific need.

        I am curious what game development use cases you're thinking of that commonly require pointers to pointers.

        • Multidimensional arrays and pointer-out parameters.

          You can get around pointers to pointers if you're writing code yourself, but often times people use an SDK or code in teams. The 2007 Source SDK counts over 1000 pointers to pointers. Not much considering the overall size of the SDK, but enough to be inevitable.

  • Matty J

    So this was something that I'd initially glossed over, but now I'm reviewing chapters 6 & 7 before I do the deep-dive into OOP in Ch. 8.

    What this lesson essentially illustrates is a way to make a dynamically allocated array of pointers which point to a series of dynamically allocated arrays?

    Now, I'm a noob programmer. Really trying to condense code using the least amount of variables possible, but there has Got to be so many other useful ways of storing data than via this convoluted process. I mean, I appreciate the depth of what C++ is capable of, but this is like fractal programming! The scope is -inf to inf! Array within an array within an array - a series of pointers that just keep on pointing...

    I'm going to go back to building Monster structs.

  • Hexx

    Hey, I'm having a little problem with this section. I wanted to know if this is the only way to dynamically allocate a 2D array.

  • saj

    Author wrote "Note that we delete the array in the opposite order that we created it"

    I don't really see that for loop deleting the array in opposite order, It's identical to the for loop that created the array.  
    Can you please explain.

  • Hermish

    I am learning C++ and I need a 2-d array that should be created dynamically. The application is very much time critical and many of these dynamic arrays should be created. Is it good to use pointer method for that? Will it be taking too much time? What is the best option in this scenario?
    P.S. Your posts are very informative and well-written. Thanks a lot for these :)

    • Alex

      For dynamic allocation, you have to use a pointer (or use something that uses a pointer under the hood, like std::vector).

      The best starter solution is as follows: Write your own class that has a std::vector member. Your class should use reserve() to reserve the amount of vector capacity you need so you don't get a ton of reallocations. You can overload operator[] to map your 2d coordinates down to a 1d vector (per the math shown in this lesson).

      If you later find this to be too inefficient, you can later swap out the std::vector for your own code. As long as you've written your classes interface properly, the users of the class shouldn't even notice.

      If you haven't learned classes yet and want something quick and dirty, a dynamically allocated 1d array using math to reduce 2d coordinations down to a 1d array is better than a 2d dynamically allocated array.

  • hassan

    Hi Alex, Can we use loop foreach with a pointer table like this:

    int main()
        int *table = new int[5];
        for(int pointer : table)
            cout << &pointer;
        delete [] table;

    • Alex

      No, because variable table doesn't have size information available. If you want to do this, dynamically allocate a std::array<int, 5> instead.

  • Is this a safe way to allocate/release a 3d array or will my code cause memory leaks or other problems ?

  • hrmn

    How this works?

    We can then access our array like usual:


  • Rohit N

    i feel like these concepts would be fairly easy to understand if c++ syntax wouldn't be so damn unintuitive sometimes

  • Benjamin Collins

    "With this method, because each array column is be dynamically allocated independently,"

    Did you mean, "TO be dynamically allocated"?

    Other than that, this lesson is a bit over my head. I'll come back to it when I need it. I'm really happy such a comprehensive tutorial for how to use C++ is available free on the internet. An important skill used to build to a career for yourself, and all the information to learn it can be accessed by anyone at anytime. The internet is a miracle.

    • Alex

      I removed the word "be" because it seemed extraneous.

      None of the future lessons build on this one, so you can skip it and come back to it later just fine.

  • Shivang

    Hi Alex,

    Thanks for amazing tutorials. I was playing with dynamic allocation of 2D array and was using for-each loop to display. Couldn't seem to get it right..
    Here's the code:

    const int row=5;
    const int col=5;
    int (*arra)[5]=new int[row][5]{

    cout<<"\n Print dynamic 2d array:\n"<<std::endl;
    for(auto i:arra)
            for(auto j:i)
                cout<<" "<<arra[i][j];

    /* Usual way for loop printing
    for(int i=0;i<row;i++)
        for(int j=0;j<col;j++)
            cout<<" "<<arra[i][j];


  • ingenuite

    Hello, everybody.
    Maybe, there are lots of guys who get stuck in this little puzzle. I was too. Here I would like to give some advice to conquer this problem.

    First, if we create a 1-D array, just like this: int array[2]; we have to understand two things:
    what's the same between "array" and "&array"? and what's the different between them? if we std::cout << array; and std::cout << &array; we will get something astonishing at first! program printed two addresses which are same. This is the same between "array" and "&array", but the more important thing is that "array" and "&array" have two different types! The type of "array" is "int *",but the type of "&array" is “int **” which contains the information about how long the array is.

    Second, Find more information to understand this clearly or write some codes by yourself to get it. I recommend you two information sources:


  • Jaideep

    Hey Alex,
    In your code at:

    I think on the left hand side it should be like int *(*array)[5] as:
    The key here is to remember that our new int[10][5] will return an array of size 5 where each element will be pointer to an array of integer of size 10.
    So i think LHS should be really like int *(*array)[5] because then it will that: array is a pointer to an array of size 5 which points to integer.

    • Alex

      Your suggestion doesn't compile. I believe it's correct as written. int x[5] would be an array of 5 integers. int (*x)[5] would be a pointer to an array of 5 integer pointers.

      Edit: Jaideep pointed out that I made a mistake here, so I've edited the comment to avoid confusion for other readers.

    • Jaideep

      Hey Alex,
      Sorry for the late reply
      I think you should go and once check the link
      As per that link i think int (*x)[5] should be: x is a pointer to array of 5 integers and for what you are saying i think we should remove the paraenthesis and it should be int *x[5]. Isn't it?

      • Alex

        Yes, you're correct. I always mess this one up.

        int (*x)[5] is a pointer to an array of 5 integers. int *x[5] is an array of 5 pointers to integers.

        That said, int (*x)[5] is the correct one to initialize with a dynamically allocated int[10][5], because the dynamically allocated memory always returns a single address, which we need to store in a pointer.

        • Jaideep

          I think my real problem is that i don't clearly understand how the following works:
          int *ptr= new int[25];
          Like as per the above definition ptr is a pointer to integer but i think it should be like int (*ptr)[25] which reads like ptr is a pointer to an array of 25 integers but that doesn't compile correctly.So what's wrong here?

          Also sir i would be highly grateful if i could get your email or you can inbox me in my email.Actually i have a lot of questions.
          Thank you.

          • Alex

            Yeah, this is super confusing, and that's due to the way C++ deals with array evaluation. Let's start with a simple example:

            ptr is a pointer to an integer. When an array is evaluated, it is converted from an "array of type" to a "pointer to type" that points to the first element of the array. Thus, arr is converted from an array of 25 integers to an integer pointer that points to the first element. Because arr is an integer pointer, we can use it to initialize ptr.

            It might seem like this should work too. But remember, arr decays to a pointer to int. So we're trying to initialize a pointer to an array of 25 integers with a pointer to an integer. That's a type mismatch.

            If we want to do this, we actually need to do this instead:

            In this case, arr doesn't decay -- instead, arr a pointer to an array of 25 integers, which is what ptr is too. So this works.

            Now, back our dynamic allocation case. When we allocate an array using new T[n], a "pointer to type" is returned, not a "pointer to an array of type". So we have to assign this to a single pointer, not a pointer to an array.

  • TuttyFruty

    Firstly, thanks you a lot for these amazing tutorials!

    I'm having trouble to understand multidimensional arrays' columns and rows system.

    in this part of code, i think it implies that the rows are the second part of the array declaration brackets which is [5].
    But in this part of code when declaring a not known sized array

    It implies that the second part of the array declarition brackets is columns. At first glance i thought it would be reversed but i thought ;anyway it would  still do our work. But!!! you said :

    array[9][4] = 3; // This is the same as (array[9])[4] = 3;

    How could this be same as the original array declaration. I still think it would be reversed= (columns , rows) to----> (rows,columns).

    Please help me to understand it!

    • Alex

      Using row-major order, the second subscript is col, not row. Given that, the rest makes sense, doesn't it?

      • Tuttyfruty

        Okey then,  what does new int[10] [5]  do?
        Does it create 10 "pointers"  which point to 5 sized arrays or the reverse(create 5 "pointers"  which point to 10 sized arrays)?
        or maybe i didn't get it at all:S

  • Luhan

    I made a code which i think can help someone trying to understand what happens when you change the value of a pointer pointing to a pointer in a function.

  • jenifer

    Array of pointers to C-style strings:

    Can u explain me how this code works?

    • Alex

      This is an array where each element is of type char* (a pointer to a char). The string literals "Great", "C++", "tutorial", and "" are placed somewhere in memory by the compiler, and the addresses of those strings are placed into each element of the array accordingly.

      To be more correct, each element of the array really should be a const char * rather than a non-const char *.

  • Satwant

    To access the two dimensional array i had to dereference it. but above it is shown we can directly access array like this : array[9,4]=3;
    Please help me with above program, its output   doesnt seem to be right.

  • wq1751

    What does the following line means?

    char *atsymb = (char*)AtSymb;

  • Surya

    How is the memory allocated to dynamic multi-dimension array using the

    deleted? should I just use

    or is there a different syntax?

    • Alex

      The memory should be allocated as a contiguous chunk of m*n integers.

      In this case, because you're doing a single allocation, you should be able to do a single array delete to deallocate it.

      • davconde

        Hi, Alex.

        After reading this lesson I've searched on the Internet for an answer like this without success. I think it would be cool to add an explanation like the one in your comment to this lesson.

  • Matt


    Under "Pointers to Pointers", you wrote:

    "Note that you can not set a pointer to a pointer directly to a value...
    int **ptrptr = &&value  // not valid...
    This is because the address of operator (operator&) requires an lvalue, but &value is an rvalue."

    Even after looking up the definitions of lvalue and rvalue, I still don't understand what you mean by this last sentence. Could you explain it in a different way?

    Also, I found a small typo midway through "Two-dimensional dynamically allocated arrays". You wrote:
    "...because each array column is be dynamically allocated independently...".

    • Alex

      Okay, I'll try. Let's go back to the definition of lvalue and rvalue.
      lvalue = an object that persists beyond a single expression, like a normal variable. You can take an address of one of these.
      rvalue = a temporary value that doesn't persists beyond a single expression (e.g. the result of 2+3). You can't take an address of one of these because the address is meaningless outside of the expression.

      So consider something like int **ptrptr = &&value. First, the compiler evaluates &value. value is an lvalue, and you _can_ take its address using the & symbol. However, the result of &value is a temporary pointer holding the address of value -- and because it is a temporary value that doesn't exist beyond the expression, that makes the result of that evaluation an rvalue. So when we try to take the address of THAT (the left-most ampersand), we get an error, because you can't take the address of an rvalue.

      Make sense?

  • Kattencrack Kledge

    Can you tell me what is happening in these codes below? I really do not understand what is happening:


    • Kattencrack Kledge

      Nevermind for the second  code, I managed to understand it by seeing what each thing does:

      But I still don't understand this:

    • Alex

      The bottom case is more straightforward. Array is a single-dimensional array of size 10, with each array element being an integer pointer (these are our rows). For each of the 10 elements, we're stepping through and dynamically allocating an array of size 5 (these are our columns). When we use array[x][y], array[x] is dereferenced to select the row, and then [y] is dereferenced to get the element within that column.

      In the top case, array is also a single-dimensional array of size 10, but each array element has type int[5]. The compiler can hook everything up for us so it works the same way as the above case, but without us having to dynamically allocate each column by hand.

  • Elpidius

    I thought I'd try to dynamically allocate a three-dimensional array. Note I've left the number of layers, rows and columns as the values 2, 10 and 5 respectively to make logic behind the code easier to understand.

    We can allocate the arrays in separate loops within loops (for the rows + columns):

    Or in one loop within a loop (for the rows + columns):

    We then assign values to each array element:

    Accessing the element of a dynamic three-dimensional array is analogous to a fixed three-dimensional array:

    To deallocate the arrays in separate loops within loops (for the rows + columns):

    delete[] array[0][0] -- deletes the int[5]
    delete[] array[0][1] -- deletes the int[5]
    delete[] array[0][2] -- deletes the int[5]
    delete[] array[0][9] -- deletes the int[5]

    delete[] array[0] -- deletes the int*[10]
    delete[] array[1] -- deletes the int*[10]

    To deallocate the arrays in one loop within a loop (for the rows + columns):

    Putting all the code together:

    I hope this helps anyone trying to do this!

    • Darren

      Brain. Is. Melting...

      • Alex

        Seriously. :) Flattened arrays are so much easier to work with.

        • Darren

          I'm going to be starting a new job in about a month's time doing C++ programming, initially refactoring some old C and Fortran code into something more modern and maintainable, then adding more functionality once I've got it doing what the old code could do. Among other things there is some linear algebra involved, so manipulation of matrices and vectors, that is currently done using Fortran's LAPACK. I essentially have three options: I either try to interface C++ with Fortran but don't think this is straightforward (or lends itself to maintainability or cross-platform compatibility): I write my own classes and functions to handle linear algebra (time consuming with lots of potential for error); or I use a third party library that is thoroughly tested, robust, and stable (this appears to be the best option). I've had some experience using a library called 'Eigen' that appears to be my best bet. Once I get the code up and running using Eigen, say, then I could perhaps look at writing my own classes if we need to streamline the code or improve performance (which I doubt as Eigen does some weird and wonderful things that make it run quickly and accurately).

          Anyway, the point I'm making here is that because C++ has been around for nearly 3 decades(?) there are many libraries out there that will probably have solved most of the problems you will encounter, such as how to efficiently implement and manipulate multi-dimensional matrices in a user friendly manner. For example, look at Boost. However, having a firm understanding of the fundamentals of the language is absolutely necessary in being able to work with these libraries and if possible extend them to make them do what you want. It's the reason why I'm running through these tutorials.

          • Alex

            Great points. There are benefits both to using your own code, and using code out of a library. However, having been involved in creation and maintenance of some very large apps, I'd lean towards favoring library functionality if that meets your needs, rather than recreating the wheel. It's less likely to be buggy, is probably more optimized, and if the library gets updated, you get more functionality for "free".

            One other option I've seen employed to good use is to "extend" library functionality via inheritance (or composition) -- that way you can complement the library functionality with anything you additionally need that it doesn't provide without it being too disjoint.

  • Nyap

    This is confusing

    • Alex

      Yeah, it is a little bit, and it's hard to explain. The good news is that you'll almost never need to use it, so if you're finding it confusing, just move on. You can always come back later if needed.

      • Elpidius

        Hey Alex, I think you did a wonderful job explaining pointers to pointers. I'm sure your explanation is better than most textbooks out there!

  • Federico

    I have a question:

    For the function funz i have a warning: address of local variable ‘var’ returned [-Wreturn-local-addr]
    and this is ok, but not for function gunz.
    The output is:
    segmentation fault

    It isn't the same situation?

    Thanks and sorry for my english.

  • raha

    Hello, thank you so much for the great website, I have a problem in calling a matrix to a function, my main function is as following,

    I've defined matrix X and vector y, Im filling these two by function ReadData, and everything is fine by now, but when I try to pass matrix X to function LogReg, which has defined as "double LogReg(double **X, double *y, Parameter* param, Objective* obj)", Im getting "segmentation fault", it happens when I want to use the elements of matrix X such X[i][j], but when I use the elements of vector y such y[i], everything is fine, the thing is why I can pass X to function ReadData(which has been defined in the same file as main) but I can not do the same thing with function "LogReg" which has been define in a header file..

    Thank you so much for your help..

  • Narendra Kangralkar

    Below is the better way of allocating memory to 2-D array. It requires only 2 calls to allocate/deallocate memory regardless of number of rows and columns.

    • Elpidius

      Hi Narendra,

      Accessing memory from a "flattened 2-D array", i.e. a 1-D array, using a 2-D array nullifies the need of "flattening" the 2-D array in the first place. You've basically created a "flattened" 1-D array in array[0], then used a 2-D array in array[1] to array[9] to access this 1-D array. What's the point in that?

      Furthermore you're using twice the amount of memory, since both an int and a pointer to an int take up 4 bytes of memory (on a 32-bit machine). The first row (row 0) contains the data, and the rest of the rows simply hold addresses. Nevertheless I've tried to understand your code and have explained what is happening below.

      You've explicity assigned each pointer to pointer, to point to the address of every 5 array elements (columns) of array[0] (row 0).

      The array assigned to array[0] is illustrated as:

      [0][0]  [0][1]  [0][2]  [0][3]  [0][4] [0][5] [0][6] etc... [0][49] // row 0

      The rows pointed to colums is illustrated as:

      [1][0] = &[0][5] // row 1 (2nd row) points to column 5 (6th column)
      [2][0] = &[0][10] // row 2 (3rd row) points to column 10 (7th column)
      [3][0] = &[0][15]
      [4][0] = &[0][20]
      [5][0] = &[0][25]
      [6][0] = &[0][30]
      [7][0] = &[0][35]
      [8][0] = &[0][40]
      [9][0] = &[0][45]

      Conceptually our final array is as follows:

      [0][0]  [0][1]  [0][2]  [0][3]  [0][4] [0][5] [0][6] etc... [0][49] // row 0
      [1][0]  [1][1]  [1][2]  [1][3]  [1][4] // row 1 -- points to [0][5] to [0][9]
      [2][0]  [2][1]  [2][2]  [2][3]  [2][4] // row 2 -- points to [0][10] to [0][14]
      [9][0]  [9][1]  [9][2]  [9][3]  [9][4] // row 9 -- points to [0][45] to [0][49]

      Here's your code which I've commented:

      Despite it being easier to access this array, it takes up double the memory and the for loop in particular is more difficult to understand. Alex's method is much easier and doesn't take up any additional memory.

      • Elpidius

        The code I commented above had typos in them. Here’s the corrected comments:

        • Elpidius

          Further typos/edits in the comments:

      • Elpidius

        Further explanation of a comment:

        Remember, when the compiler sees the subscript operator ([]), it actually translates that into a pointer addition and dereference! Generalizing, array[n] is the same as *(array + n), where n is an integer.

        Revisit lesson 6.8a — Pointer arithmetic and array indexing, if you're having trouble understanding this.

  • cesare

    I need a little clarification about what you say here:

    "With this method, because each array column is be dynamically allocated independently, it’s possible to make dynamically allocated two dimensional arrays that are not rectangular. For example, we can make a triangle-shaped array:"

    And then:
    "In the above example, note that array[0] is an array of length 1, array[1] is an array of length 2, etc…"

    Well, from my point of view, during the first iteration of the loop, the value of 'count' equals 0, so the instruction run like this:

    On the left hand side it clearly refer to the first position in the array, but on the right hand side it seems to allocate an array with length 0 not length 1.
    Am I missing something or is it just a typo?

  • Anton

    Regarding dynamic multidimensional arrays Ivor Horton writes in his book "Beginning Visual C++ 2013" about another way to create such matrices:

    or for one-line initialization

    for three-dimensional matrices:

    and so on ...

    As for the way to remove the kebab he suggests:

    I'm confused here. This couldn't possibly be a proper way to declare a true dynamic multidimensional array. Firstly, I don't truly understand the syntax and secondly the code:

    looks like

    Hayl, I don't even understand what it does! It doesn't look like something that the compiler would accept.

    If you want to check it out it is found in chapter 4 ("Arrays, Strings and Pointers") in section [i]???[b]num[/b]???[/i] ("Dynamic Memory Allocation") in the last subsection [i]???[b]num.num[/b]???[/i] ("Dynamic Allocation of Multidimensional Arrays").

    • Alex

      That's super neat. I've updated the lesson to incorporate this. Thanks for the tip!

      means (in English) define a pointer that points to an object of type double[4]. In other words, *pbeans (or pbeans[0]) has type double[4].

      The {} aren't necessary, but can be used to initialize the array to the default value for the type (in this case, the default value for double is 0.0).

  • venkata prasad

    I read everywhere that if I have a need to do arithematic operations on pointers always choose pass by pointer mentod over pass by reference method.

    but what about this code?

    incrementptr1(int *ptr1)


    return 0;


    incrementptr2(int* &ptr2)


    int main()


       int value=5;

    return 0;


    with the increment2 method I could increment the pointer though I did pass it by reference.

    does this work?

    • Alex

      It really depends on what your intent is. If you want to increment the pointer inside the function without affecting the argument, pass the pointer by value (incrementptr1). If you want the function to be able to change the argument, then pass the pointer by reference (incrementptr2).

  • Avneet

    Doesn't this code causes memory leak:

    In main (), a pointer to int is declared. It's  address is then sent to allocateArray() that returns a bool. We dereference the pointer (with single asterisk) and get access to a pointer. Dynamically Allocate some memory and then return true, in this case. Now control is back to main (). main () neither uses that memory, nor deallocates it. When 'array' is going out of scope, only reference to that memory is destroyed and results a memory leak. Am I right? Correct me if not. The next code also has a memory leakage problem I think.

    And a confusion. We are sending the address of 'array' by value, that means a copy of that address would be passed. Isn't the copy of the address is same as the real address. I mean, array and ptr are pointing to same address right? So, main's 'array' can deallocate the dynamically allocated memory in allocateArray(), where 'ptr' is controlling the dynamic allocation? Confused? My bad english :-(

    • Alex

      Yes, the memory is never deallocated. It wasn't relevant to the example so I didn't flesh out that part of the example. However, I think it's good practice, so I've added it. Thanks for the thought.

      Consider this code:

      This is a pass-by-value example. In this case, ptr gets a copy of array's value. We allocate memory to ptr, but the address of that memory never gets assigned back to array because ptr is a copy.

      In the example in the lesson, we are sending the address of array by address, not by value. So the ptr is set to the _address_ of array. Think of it this way:

      ptr -> array -> array element 0

      In this case, when we dereference ptr, we get array (which itself points to the array). By allocating memory to *ptr, we're essentially changing the address of array, which is why when we return to main, array is still pointing at the allocated memory.

      This allows array to deallocate the memory allocated in allocateArray() because array is a valid pointer to that memory.

      On second thought, I think I'm going to remove the example altogether. It's a little complicated for this point in the tutorials, and we haven't even hit the lessons on pass by value, pass by address, and pass by reference yet.

    • Elpidius

      Hey Avneet,

      The following code does not cause a memory leak. I also commented everything to try and illustrate what is happening:

Leave a Comment

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