Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
Solved

# Assigning 2-dimensional array with new

Posted on 2004-10-21
Medium Priority
252 Views
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
0
Question by:steva
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 6
• 5
• 5
• +3

LVL 55

Expert Comment

ID: 12375513
Some trick:

typedef struct {
char line[30];
} TLine;

int i=20;
TLine *p;
p = new TLine[i];

0

LVL 4

Expert Comment

ID: 12377129
int[][] a2 = new int[20][30];
0

LVL 4

Expert Comment

ID: 12377131
or char[][] a2 = new char[20][30];

... as it were :)
0

LVL 2

Expert Comment

ID: 12377335
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.
0

LVL 4

Expert Comment

ID: 12377377
That is a whole lot of unnecessary work, though it works.
0

LVL 15

Expert Comment

ID: 12377471
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.
0

LVL 30

Expert Comment

ID: 12379253
>> 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.
0

LVL 30

Expert Comment

ID: 12379271
>>char[][] a2 = new char[20][30];

That does not even compile on a C++ compiler.
0

LVL 30

Expert Comment

ID: 12379297
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)?new T[row*col]:NULL){}
dynamic_2d_array():m_row(ROW_T),m_col(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_data) 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;
};

0

LVL 30

Expert Comment

ID: 12379306
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;
0

LVL 55

Expert Comment

ID: 12380217
steva,
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
0

Author Comment

ID: 12382878
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
0

LVL 30

Accepted Solution

Axter earned 500 total points
ID: 12387638
>> As you requested, the intention of the two-dimensional array is to hold an array of lines.

For this requirement, it would be safer if you use a vector of std::string.

std::vector<std::string> MyArray;

std::string LineStr;

while(std::getline(myfstream, LineStr))
{
MyArray.push_back(LineStr);
}

By using the above container, you don't have to worry about the value of "i", and you don't have to worry about a 250 bound limit.

Otherwise, you would have to run through the file, to determine the quantity of lines, and then create your dynamic array.
Then run through the file again, to actually fetch the data.
That would be very inefficient, and not as safe is the vector container.
0

Author Comment

ID: 12396325
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
0

LVL 4

Expert Comment

ID: 12396579
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.
0

LVL 30

Expert Comment

ID: 12398916
>>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.
0

Author Comment

ID: 12402029
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
0

LVL 4

Expert Comment

ID: 12406391
in order to use  std::getline()  you must have "using namspace std; " at the top
0

Author Comment

ID: 12406583
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?
0

LVL 15

Expert Comment

ID: 12406998
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
0

Author Comment

ID: 12415995
Thanks guys for all your help.   I went with Axter, though you all provided useful information.

Steve
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generatâ€¦
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why tâ€¦
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
###### Suggested Courses
Course of the Month10 days, 23 hours left to enroll