Solved

Assigning 2-dimensional array with new

Posted on 2004-10-21
202 Views
Last Modified: 2010-04-01
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
    21 Comments
     
    LVL 55

    Expert Comment

    by:Jaime Olivares
    Some trick:

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

        int i=20;
        TLine *p;
        p = new TLine[i];
       
       
    0
     
    LVL 4

    Expert Comment

    by:nagraves
    int[][] a2 = new int[20][30];
    0
     
    LVL 4

    Expert Comment

    by:nagraves
    or char[][] a2 = new char[20][30];

    ... as it were :)
    0
     
    LVL 2

    Expert Comment

    by:bcsonka
    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

    by:nagraves
    That is a whole lot of unnecessary work, though it works.
    0
     
    LVL 15

    Expert Comment

    by:efn
         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

    by:Axter
    >> 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

    by:Axter
    >>char[][] a2 = new char[20][30];

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

    Expert Comment

    by:Axter
    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

    by:Axter
    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

    by:Jaime Olivares
    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
    0
     

    Author Comment

    by:steva
    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

    by:
    >> 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

    by:steva
    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

    by: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.. sdt::getline uses strings, iostream::getline doesn't afaik.
    0
     
    LVL 30

    Expert Comment

    by:Axter
    >>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

    by:steva
    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

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

    Author Comment

    by:steva
    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

    by:efn
    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

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

    Steve
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Course: From Zero to Hero with Nodejs & MongoDB

    Interested in Node.js, but don't know where to start or how to learn it properly? Confused about how the MEAN stack pieces of MongoDB, Expressjs, Angularjs, and Nodejs fit together? Or how it's even possible to run JavaScript outside of the browser?

    Suggested Solutions

    What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
    C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
    The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
    The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

    846 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    5 Experts available now in Live!

    Get 1:1 Help Now