steva
asked on
Assigning 2-dimensional array with new
Anyone know how to assign memory for a two-dimensional array of characters with new? I've tried:
int i=20;
char ** p;
p = new char [i][30];
Thanks,
Steve
int i=20;
char ** p;
p = new char [i][30];
Thanks,
Steve
int[][] a2 = new int[20][30];
or char[][] a2 = new char[20][30];
... as it were :)
... as it were :)
Hi,
Here's another way to allocate a two-dimensional array of characters:
========================== ========== ========== ========== ========== ==========
// Allocate array of character pointers
char **array2D = new char* [20];
// For each character pointer, allocate an array of characters
for(int i = 0; i < 20; i++)
{
array2D[i] = new char[30];
}
//
// Utilitze array2D
//
// For each character pointer allocated above, delete its array of characters
for(int j = 0; j < 20; j++)
{
delete [] array2D[j];
}
// Finally, delete the array of character pointers
delete [] array2D;
========================== ========== ========== ========== ========== ==========
I hope that helps.
Here's another way to allocate a two-dimensional array of characters:
==========================
// Allocate array of character pointers
char **array2D = new char* [20];
// For each character pointer, allocate an array of characters
for(int i = 0; i < 20; i++)
{
array2D[i] = new char[30];
}
//
// Utilitze array2D
//
// For each character pointer allocated above, delete its array of characters
for(int j = 0; j < 20; j++)
{
delete [] array2D[j];
}
// Finally, delete the array of character pointers
delete [] array2D;
==========================
I hope that helps.
That is a whole lot of unnecessary work, though it works.
int i=20;
char (*p)[30];
p = new char [i][30];
The second line declares p as a pointer to an array of 30 chars. The parentheses are required--without them, it declares p as an array of 30 pointers.
char (*p)[30];
p = new char [i][30];
The second line declares p as a pointer to an array of 30 chars. The parentheses are required--without them, it declares p as an array of 30 pointers.
>> That is a whole lot of unnecessary work, though it works.
I'ts not unnecessary work.
The code you posted, will not give you the desired results for a two dimensional array.
I'ts not unnecessary work.
The code you posted, will not give you the desired results for a two dimensional array.
>>char[][] a2 = new char[20][30];
That does not even compile on a C++ compiler.
That does not even compile on a C++ compiler.
I recommend using a 2DArray class or vector<vector<> > type class.
It's much safer then using pointers.
Here's a simple 2DArray class
template < class T, int ROW_T = 0, int COL_T = 0 >
class dynamic_2d_array
{
public:
dynamic_2d_array(int row, int col):m_row(row),m_col(col) , m_data((row!=0&&col!=0)?ne w T[row*col]:NULL){}
dynamic_2d_array():m_row(R OW_T),m_co l(COL_T), m_data(new T[ROW_T*COL_T])
{if (!COL_T || !ROW_T) {int x[ROW_T] = {{ROW_T}};int y[COL_T] = {{x[0]}};}}
~dynamic_2d_array(){if(m_d ata) delete []m_data;}
inline T* operator[](int i) {return (m_data + (m_col*i));}
inline T const*const operator[](int i) const {return (m_data + (m_col*i));}
private:
const int m_row;
const int m_col;
T* m_data;
};
It's much safer then using pointers.
Here's a simple 2DArray class
template < class T, int ROW_T = 0, int COL_T = 0 >
class dynamic_2d_array
{
public:
dynamic_2d_array(int row, int col):m_row(row),m_col(col)
dynamic_2d_array():m_row(R
{if (!COL_T || !ROW_T) {int x[ROW_T] = {{ROW_T}};int y[COL_T] = {{x[0]}};}}
~dynamic_2d_array(){if(m_d
inline T* operator[](int i) {return (m_data + (m_col*i));}
inline T const*const operator[](int i) const {return (m_data + (m_col*i));}
private:
const int m_row;
const int m_col;
T* m_data;
};
Example usuage:
dynamic_2d_array < int > dyn_2dArray(Q_Col, Q_Row);
for(int i0 = 0; i0 < Q_Col; ++i0) {
for(int i1 = 0; i1 < Q_Row; ++i1) {
dyn_2dArray[i0][i1] = random_value();
cout << dyn_2dArray[i0][i1] << endl;
dynamic_2d_array < int > dyn_2dArray(Q_Col, Q_Row);
for(int i0 = 0; i0 < Q_Col; ++i0) {
for(int i1 = 0; i1 < Q_Row; ++i1) {
dyn_2dArray[i0][i1] = random_value();
cout << dyn_2dArray[i0][i1] << endl;
steva,
Please explain us your intention to use the bidimensional array.
If just need to have an array of "strings", then my example could be helpful and simple.
If you need a true bidimensional array, then you will need to create a specialized C++ class.
I will retouch my example a bit:
typedef struct {
char col[30];
} TLine;
int i=20;
TLine *p;
p = new TLine[i];
You can use it as:
p[10].col[15] = 'A'; // single char assignment
or
strcpy(p[10].col, "test"); // entire string assignment
Please explain us your intention to use the bidimensional array.
If just need to have an array of "strings", then my example could be helpful and simple.
If you need a true bidimensional array, then you will need to create a specialized C++ class.
I will retouch my example a bit:
typedef struct {
char col[30];
} TLine;
int i=20;
TLine *p;
p = new TLine[i];
You can use it as:
p[10].col[15] = 'A'; // single char assignment
or
strcpy(p[10].col, "test"); // entire string assignment
ASKER
As you requested, the intention of the two-dimensional array is to hold an array of lines. The diminsions will be [i][250], where I'm allowing 250 characters per line and "i" is determined after I've done getline() to EOF, i.e., I know how many lines are in the file. I will then read the lines of the file into the array, edit the individual lines (without extending any line beyond its 250 allotted chars) and write the array back out to the file.
Steve
Steve
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Axter,
Your vector of LineStrs has an elegant feel, but I'm afraid it will force me to learn a lot more C++ than I intended for this small project. How do I find out more about the characteristics of an std::string, for example? Why do we need to bring in std::? How is std::getline() different from the iostream getline()? I couldn't find anything in the VC++ documentation about std::stuff. Your code compiles under VC++ 6.0, but generates warnings about reverse interators being truncated to 255 characters. What are these about?
Steve
Your vector of LineStrs has an elegant feel, but I'm afraid it will force me to learn a lot more C++ than I intended for this small project. How do I find out more about the characteristics of an std::string, for example? Why do we need to bring in std::? How is std::getline() different from the iostream getline()? I couldn't find anything in the VC++ documentation about std::stuff. Your code compiles under VC++ 6.0, but generates warnings about reverse interators being truncated to 255 characters. What are these about?
Steve
std::getline() makes sure that you're using the getline in the std namespace. (when you use: using namespace std;) 'using namespace std' is the namespace which the entire Standard c++ library is declared.. sdt::getline uses strings, iostream::getline doesn't afaik.
>>reverse interators being truncated to 255 characters. What are these about?
That's a bug in the compiler, which you can ignore.
You can remove the warnings by adding the following line to the top of your code:
#pragma warning(disable: 4786)
>>How do I find out more about the characteristics of an std::string, for example?
If you're using VC++, then just use the compiler's help file.
Double clikc on string in your code, and then press F1
You can also check out the MSDN:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcstdlib/html/vclrfcpluspluslibraryoverview.asp
Both string and vector are listed in above site. Click on the object you want info on, and then you can click on the [member] link listed at the bottom left corner of the web page.
Both string and vector's are pretty simple containers that can save you a lot of time coding.
That's a bug in the compiler, which you can ignore.
You can remove the warnings by adding the following line to the top of your code:
#pragma warning(disable: 4786)
>>How do I find out more about the characteristics of an std::string, for example?
If you're using VC++, then just use the compiler's help file.
Double clikc on string in your code, and then press F1
You can also check out the MSDN:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcstdlib/html/vclrfcpluspluslibraryoverview.asp
Both string and vector are listed in above site. Click on the object you want info on, and then you can click on the [member] link listed at the bottom left corner of the web page.
Both string and vector's are pretty simple containers that can save you a lot of time coding.
ASKER
nagraves,
>>std::getline() makes sure that you're using the getline in the std namespace. (when you use: using namespace >>std;) 'using namespace std' is the namespace which the entire Standard c++ library is declared.
So if I put 'using namespace std;' at the top of my program, can I just code 'getline()' without the std::?
Steve
>>std::getline() makes sure that you're using the getline in the std namespace. (when you use: using namespace >>std;) 'using namespace std' is the namespace which the entire Standard c++ library is declared.
So if I put 'using namespace std;' at the top of my program, can I just code 'getline()' without the std::?
Steve
in order to use std::getline() you must have "using namspace std; " at the top
ASKER
Yes, but if I put 'using namespace std;' at the top is it then understood that getline() is the std version so I don't need to write std::getline() everytime?
Yes, if you put "using namespace std;" at the top, you don't need to prefix "getline" with "std::"--unless you have something else called "getline" in scope.
If you would prefer to avoid all this standard library stuff, you can just use the declaration I posted above. The only disadvantages are that you have to read the file twice and you have to make sure the lines are no longer than 249 characters, as Axter pointed out. If you can live with those disadvantages, you don't have to grapple with the standard library or namespaces.
--efn
If you would prefer to avoid all this standard library stuff, you can just use the declaration I posted above. The only disadvantages are that you have to read the file twice and you have to make sure the lines are no longer than 249 characters, as Axter pointed out. If you can live with those disadvantages, you don't have to grapple with the standard library or namespaces.
--efn
ASKER
Thanks guys for all your help. I went with Axter, though you all provided useful information.
Steve
Steve
typedef struct {
char line[30];
} TLine;
int i=20;
TLine *p;
p = new TLine[i];