Thread: Dynamic 2d array

  1. #1
    Registered User
    Join Date
    Jan 2010
    Posts
    17

    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. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Well you also need

    delete [ ] globalCO.pcode;

    But you would be better off using std::vector if at all possible.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jan 2010
    Posts
    17
    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. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    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.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Jan 2010
    Posts
    17
    Quote Originally Posted by Elysia View Post
    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. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    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.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Jan 2010
    Posts
    17
    Ok, thanks.

  8. #8
    Registered User
    Join Date
    Jan 2010
    Posts
    17
    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. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    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.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote 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.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Jan 2010
    Posts
    17
    I did not know about the min and max functions, but now I do. That all makes sense, thanks to both of you.

  12. #12
    Registered User
    Join Date
    Jan 2010
    Posts
    17
    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....
    
    }
    
    void globalC::add_double_quotes(string &str)
    {
        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);
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Copy array into a Dynamic array
    By pantherman34 in forum C Programming
    Replies: 15
    Last Post: 05-01-2010, 10:58 PM
  2. dynamic array
    By Antimodes in forum C++ Programming
    Replies: 8
    Last Post: 04-23-2009, 06:06 AM
  3. 2d dynamic array
    By eklavya8 in forum C++ Programming
    Replies: 2
    Last Post: 07-21-2008, 12:19 PM
  4. Dynamic structure with array and array count
    By Nazgulled in forum C Programming
    Replies: 14
    Last Post: 06-08-2007, 10:10 PM
  5. dynamic array
    By linuxdude in forum C Programming
    Replies: 5
    Last Post: 07-13-2004, 02:33 AM