1. ## Dynamic 2d array

I found some code for allocating and deallocating a dynamic 2d array, I modified it for my program and everything seems to work as it should. However I saw a comment saying this code could cause some problems, but it did not say what problems. So, Will this code cause any problems and if so what?

Code:
globalCO.pcode = new string*[HEIGHT*10];
for(int n = 0; n < HEIGHT*10; n++)
{
globalCO.pcode[n] = new string[WIDTH];
}

for (int n=0; n<HEIGHT*10; n++)
{
delete [ ] globalCO.pcode[n];
}

2. Well you also need

delete [ ] globalCO.pcode;

But you would be better off using std::vector if at all possible.

3. I knew someone would mention using a vector, I am going to do some reading on them and as long as it doesn't mean altering the structure of my program too much, I will probably implement them. What are the main advantages of using a vector instead of an array?

Thanks

4. Less lines of code. Automatic memory management. Bounds checking.
To allocate a 2D array, you may do:
std::vector<std::vector<T>> v(n, std::vector(m));
Where n is the inner dimension and m is the outer. Eg, it would be similar to something like
T v[n][m];
Don't forget to use the at member function for bounds checking.

5. Originally Posted by Elysia
Less lines of code. Automatic memory management. Bounds checking.
To allocate a 2D array, you may do:
std::vector<std::vector<T>> v(n, std::vector(m));
Where n is the inner dimension and m is the outer. Eg, it would be similar to something like
T v[n][m];
Don't forget to use the at member function for bounds checking.
Thanks, I am going to look into vector's. I have just been reading about bounds checking, from what I understand there are 2 types, index checking, range checking.

Now I get index checking, making sure that the elements that are accessed, are within the arrays HEIGHT,WIDTH. With range checking though, I know the ranges of char's int's signed, unsigned, etc, but what about strings? Do they have a range or can I put a string of any length into an array\vector?

6. Checking for overflow/underflow typically isn't your job (it can be difficult). I'd say you just have to make sure that the index are within bounds.

7. Ok, thanks.

8. One other question. In the code you posted, you declare the std namespace before vector, is there an advantage to doing this over putting using namespace std in the declarations.

9. Yes. If you use using namespace std, then everything in the std namespace will be imported into the global namespace.
Did you know there is, for example, a min and max function in std?
That means, that if you use using namespace std, you will get problems when using min or max as function names or variables names in your code due to name collisions. Those problems are avoided when explicitly typing the namespace.
It's a trade-off really. It means more typing, but it also means less name collisions, so I prefer it.

10. Originally Posted by redsfan
In the code you posted, you declare the std namespace before vector, is there an advantage to doing this over putting using namespace std in the declarations.
We say that Elysia qualified the name with the namespace name (e.g., std::vector<T>) rather than use a using directive (e.g., using namespace std; ) or using declaration (e.g., using std::vector; )

The advantage of qualifying names is that it avoids name collision. The disadvantage is that then names can become rather verbose, and the risk of name collision may be low. Generally, you should fully qualify names that are not within some local scope in a header, or before a header inclusion.

11. I did not know about the min and max functions, but now I do. That all makes sense, thanks to both of you.

12. I have now changed my code to use a vector instead of an array and everything is working ok, but I have an issue with one of the vector's.

I have had to declare the vector "code" globally to get the program to work, but my understanding is that, by declaring it globally the vector is allocated when the program starts, then deallocated when the program ends, which seems pointless, is this correct?

I am wanting to have it allocated when merge_code is first called, then deallocated when write_code has returned, can I do this with the vector "code"?

If not, is it possible to pass a vector to a dynamic 2d array? then could I make "code" a dynamic 2d array so I can allocate\deallocate it where I want.

Code:
vector< vector<string> > code(HEIGHT*25, vector<string>(WIDTH));

int main(void)
{
int x;

do{
cout << "\n1. some \t2. other \t0. quit" << endl;
cin >> x;
globalCO.clear_ibuffer();
switch(x)
{
case 1:
someCO.somefunc();
break;
case 2:
otherCO.otherfunc();
break;
default:
x = 0;
break;
}
}while(x != 0);

globalCO.write_code();

return 0;
}

void globalC::write_code(void)
{
ofstream outdata;

outdata.open("c:\\output.txt");

if( !outdata )
{
cerr << "Error: file could not be opened" << endl;
exit(1);
}

for (int n=0;n<HEIGHT*25;n++)
for (int m=0;m<WIDTH;m++)
outdata << code.at(n).at(m);
outdata.close();
}

void globalC::merge_code(vector< vector<string> > &pvec_code)
{
pHEIGHT = &indexH;

if (array_count == 1)
{
for(int n=0;n<HEIGHT; n++)
for(int m=0;m<WIDTH; m++)
code.at(n).at(m) = pvec_code.at(n).at(m);

*pHEIGHT = 10;
}
else if (array_count == 2)
{
for(int n=0;n<HEIGHT; n++, indexH++)
for(int m=0;m<WIDTH; m++)
code.at(indexH).at(m) = pvec_code.at(n).at(m);

*pHEIGHT = 20;
}

// More else if statements....

}

{
str = '\"' + str + '\"';
}

void globalC::clear_ibuffer(void)
{
cin.clear();
cin.ignore(100, '\n');
}

void someC::some_func(void)
{
int x;
string uinput;

vector< vector<string> > some_code(HEIGHT, vector<string>(WIDTH));

cout << "1. group \t2. rank \n3. rank1 \t4. name \n0. quit\n" << endl;
do{
cin >> x;
globalCO.clear_ibuffer();
switch(x)
{
case 1:
some_code.at(0).at(0) = "group";
break;
case 2:
some_code.at(1).at(0) = "rank";
break;
case 3:
some_code.at(1).at(1) = "rank1";
break;
case 4:
getline(cin, uinput);
default:
x = 0;
break;
}
}while(x != 0);

sort_string(uinput, some_code);
}

void someC::sort_string(string &str, vector< vector<string> > &psome_code)
{

// This function is used to sort the user input and add more code to, if necessary

globalCO.merge_code(psome_code);
}

void otherC::other_func(void)
{
int x;
string uinput;

vector< vector<string> > other_code(HEIGHT, vector<string>(WIDTH));

// Similar to someC::some_func

sort_string(uinput, other_code);
}

void otherC::sort_string(string &str, vector< vector<string> > &pother_code)
{

// This function is used to sort the user input and add more code to, if necessary

globalCO.merge_code(pother_code);
}