views:

348

answers:

4

Greetings again, and thanks once more to all of you who provided answers to the first question. The following code is updated to include the two functions per the assignment.

To see the original question, click here.

I am pretty sure this fulfills the requirements of the assignment, but once again I would greatly appreciate any assistance. Did I modify the delete statements appropriately? Thanks again.

#include<iostream>
#include<string>

int** createArray(int, int);
void deleteArray(int*[], int);

using namespace std;

int main()
{
    int nRows;
    int nColumns;

    cout<<"Number of rows: ";
    cin>>nRows;

    cout<<"Number of columns: ";
    cin>>nColumns;

    int** ppInt = createArray(nRows, nColumns);

    deleteArray(ppInt, nRows);
}

int** createArray(int nRows, int nColumns)
{
    int** ppInt = new int*[nRows];

    for (int nCount = 0; nCount < nRows; nCount++)
    {
     ppInt[nCount] = new int[nColumns];
    }

    return ppInt;
}

void deleteArray(int** nPointer, int nRows)
{
    for (int nCount = 0; nCount < nRows; nCount++)
    {
     delete[] nPointer[nCount];
    }

    delete[] nPointer;
}

P.S. Here is the assignment documentation itself, in case it helps:

(1) Design and implement a function to allocate memory for a 2-D integer array: the function is supposed to take two integers as parameters, one for number of rows and one for number of columns. You need to use “new” operator in this function. Remember that we need to first create an array of pointers. Then, for each pointer in that array, we need to create an array of integers. This function is supposed to return a pointer which points to a 2-D integer array.

(2) Design and implement a function to de-allocate memory for this 2-D array: the function is supposed to have two parameters (a pointer which points to a 2-D integer array, and the other one is number of rows in the array). In the function, you are supposed to de-allocate memory for this 2-D array using the “delete” operator. You should delete each row (an array of integers) first, and then delete the array of pointers.

A: 

Looks reasonable to me.

I'm not sure about submitting a whole new question, though. It might have been better as an amendment to the original.

Jonathan Leffler
Thank you for the input. I apologize if the second question was inappropriate; I did not see an option to amend my original question. I will keep that in mind next time. Thank you again. Take care.
ninj0rc
I suppose I should have just edited the original post. Once more I apologize, and thank you very much for taking a look at the code.
ninj0rc
+4  A: 

The code looks good.

However, there are some problems you may want to address, for us humans:

  1. Your function signatures (declarations) lack parameter names. More suitable:

    int** createArray(int rows, int columns);
    void deleteArray(int** array, int rows);
    
  2. Your function names aren't too descriptive as to what they really create/delete. create2DArray would be a wiser choice, for example.

  3. Your n prefixes to your variables hurt my eyes. numRows or rowCount is more readable.
  4. Similarly, ppInt is crazy. Try array (for nPointer as well, for consistency). (Sadly, you can't write 2dArray.)
  5. Using i as a loop counter is more common than nCount or similar (especially for array indexes). I suggest you use that instead.

Some things which go Above And Beyond, for your personal practice:

  1. Create a class which takes rows and cols as arguments to its constructor. Make sure to deallocate the array automatically.
  2. Use std::vector and create a resize member function for your class. Note that this deviates from the original question, which asked for pointers.
  3. Create a copy function and a clone function to copy data to another 2D array (possibly of a different size!) or clone an existing array.
strager
"Create a copy function [...] to copy data to another 2D array" what's wrong with a copy constructor?
Johannes Schaub - litb
never mentioned :) i think you mean 2 functions then without the class proposed before :)
Johannes Schaub - litb
Many thanks for the input. This code isn't really meant to be implemented...the goal of the assignment is to demonstrate an understanding of memory management. My professor requires that variable names be prefixed with a letter to indicate the data type; he also requires descriptive variable names
ninj0rc
'i' is a descriptive variable name, in my opinion. 'nCount' makes me think 'number of counts', which doesn't make sense. Make it 'nCounter', at least, or 'nIndex'.
strager
@strager: if the professor wants a pseudo-Hungarian notation, he probably gets it - but I agree that i is simpler to read than nCount.
Jonathan Leffler
Believe me, I would much rather be using 'x' or 'n' etc. for throwaway variables like this...but it is what it is. Thanks again guys.
ninj0rc
A: 

For "deleteArray", your prototype and definition aren't exactly the same:

void deleteArray(int*[], int);
void deleteArray(int** nPointer, int nRows)

They do have the same meaning, but for clarity I think it would be best to have them exactly the same (favoring `int**' to emphasize the fact that you're passing pointers) for consistency.

Also, include the argument names in the prototype.

Andrew Medico
Ah, thank you for pointing that out...I totally missed it. However, the mistake has taught me something..I was unaware that the two forms are syntactically identical. Thanks again!
ninj0rc
+1  A: 

Its OK.

The problem is that you are not thinking about exception safety in your code.

int** ppInt = new int*[nRows];   // ALLOC 1

for (int nCount = 0; nCount < nRows; nCount++)
{
        ppInt[nCount] = new int[nColumns]; // ALLOC 2
}

Say ALLOC 1 goes fine.
But if any of the ALLOC 2 fail then you have an exception and a severe memory leak.

For example.
You fail on the fourth call to ALLOC 2. Then you leak the memory from ALLOC 1 and the first three calls to ALLOC 2. Now in your situation the code is so trivial it probably does not matter. BUT this is the kind of thing you should always keep in mind when writting C++ code.

What will happen here if an exception is throw, what resources are going to be leaked what resources are not going to be cleaned up correctly.

I think you should think about wrapping your 2D array inside a class so that you can guarantee that memory is allocated and de-allocated correctly even in the presence of exceptions.

Martin York
I appreciate your insight. Unfortunately exception handling and debugging are topics that none of my professors have spent much time covering. Definitely two areas which I need to spend some time studying.
ninj0rc
Nice catch, @Martin York. (Pun unintended.) However, the exception would be caught by the OS, which would terminate the process and free its memory anyway (in this case). Also, a delete[] on a NULL (in case exceptions are disabled) is ignored, so deleteArray doesn't have a problem to worry about.
strager
@strager: That's fine for THIS trivial example. But in any real code that is not usually an option. This learning to do it correctly in the trivial example will save you much more time when doing it in real life.
Martin York