Thread: Dynamic Two-Dimensional Arrays

  1. #1
    Registered User
    Join Date
    Aug 2003
    Posts
    288

    Dynamic Two-Dimensional Arrays

    Hey,

    Well i was just working on an algorithm to read in a monochrome bitmap and then save each pixel to a two dimensional array, the code for loading into the array is below:

    Code:
    BYTE *dibLetter = LoadDib(sPath);
    
    iWidth = DibWidth(dibLetter);
    iHeight = DibHeight(dibLetter);
    
    DWORD dwLetter[iHeight][iWidth];
    
    if (dibLetter)
    {
    	memset(&dwLetter, 0, iHeight * iWidth);
    
    	for (int i = 0; i < iWidth; i++)
    	{
    		for (int j = 0; j < iHeight; j++)
    		{
    			dwLetter[j][i] = DibGetPixel(dibLetter, j, i);
    		}
    	}
    
    	free(dibLetter);
    	dibLetter = NULL;
    }
    anyway, when i try to compile, i get errors about the array being undefined... but i clearly define it using:

    Code:
    DWORD dwLetter[iHeight][iWidth];
    
    iHeight and iWidth are calculated before defining the array...
    
    I also tried:
    
    DWORD *dwLetter = new DWORD[iHeight][iWidth];
    Anyway, this is the first time i get an error like this :S, thanks in advance for any help

  2. #2
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    dynamically allocating arrays like that is not standard.

    You'll need something like:
    Code:
    DWORD *dwLetter = new (DWORD *)[iHeight];
    for (int i=0; i < iHeight; i++)
      dwLetter[i] = new DWORD[iWidth];
    and then to free
    Code:
    for (int i=0; i < iHeight; i++)
      delete[] dwLetter[i];
    delete[] dwLetter
    Note: I haven't tested it so I might have mistyped something in the above code

  3. #3
    Registered User
    Join Date
    Aug 2003
    Posts
    288
    thanks for the quick reply, first time i had to declare an array like this :S

  4. #4
    Registered User
    Join Date
    Aug 2003
    Posts
    288
    k, i just got home and i tried fixing it up like you said, at first it didnt compile so i edited until i could get it to compile, but now if i run the code it just exits, no errors or anything, just a clean exit, heres the code

    Code:
    BYTE **bLetter = (BYTE **)new BYTE[iHeight]; //unsure about this
    
    for (iLoop = 0; iLoop < iHeight; iLoop++)
    	bLetter[iLoop] = new BYTE[iWidth];
    
    if (dibLetter)
    {
    	memset(&bLetter, 0, iHeight * iWidth); //unsure about this
    
    	for (int i = 0; i < iWidth; i++)
    	{
    		for (int j = 0; j < iHeight; j++)
    		{
    			bLetter[j][i] = DibGetPixel(dibWord, j, i) ? 1 : 0;
    		}
    	}
    
    	free(dibLetter);
    	dibLetter = NULL;
    }
    
    if (bLetter)
    {
    	for (int i = 0; i < iHeight; i++)
    		delete[] bLetter[i];
    
    	delete[] bLetter;
    }

  5. #5
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Why are you casting the return of new?

  6. #6
    Registered User
    Join Date
    Aug 2003
    Posts
    288
    if i dont i get a 'cannot convert from 'unsigned char *' to 'unsigned char **'

    i think i was meant to put it in front of the new and not behind it :S

    i tried it like:

    Code:
    BYTE *bLetter = new BYTE[iHeight];
    
    for (iLoop = 0; iLoop < iHeight; iLoop++)
    	bLetter[iLoop] = new BYTE[iWidth];
    i get an error on the
    Code:
    bLetter[iLoop] = new BYTE[iWidth];
    cannot convert from 'unsigned char *' to 'unsigned char'
    Last edited by X PaYnE X; 08-07-2004 at 06:06 PM.

  7. #7
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    here:
    Code:
    #include <iostream>
    
    int main()
    {
      const char letters[]="abcdefghijklmnopqrstuvwxyz";
      char **arr;
      const int height = 10, width=5;
      arr = new (char *)[height];
      for (int i=0; i < height; i++)
        arr[i] = new char[width];
    
      for (int i=0, count=0; i < height; i++, count++)
        for (int j=0; j < width; j++, count++)
          arr[i][j] = letters[count % (sizeof letters-1)];
    
      for (int i=0; i < height; i++)
        for (int j=0; j < width; j++)
          cout<<arr[i][j]<<' ';
    
      cout<<endl;
    
      for(int i=0; i< height; i++)
        delete[] arr[i];
    
      delete[] arr;
    }
    obviously replace char with whatever data type you need

  8. #8
    Registered User
    Join Date
    Aug 2003
    Posts
    288
    hmm well that got it down to one error:

    Code:
    BYTE **bWord;
    bWord = new (BYTE *)[iHeight];
    syntax error : missing ';' before '['

  9. #9
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Ok that is my mistake, when I complied it I forgot to turn on -ansi and -padantic

    change:
    Code:
      arr = new (char *)[height];
    to
    Code:
      arr = new char *[height];

  10. #10
    Registered User
    Join Date
    Aug 2003
    Posts
    288
    tried that earlier, same problem, i call the function and the program just exits

    im looking through the function, theres probably a memory leak in something other than the array, thanks alot for your help though
    Last edited by X PaYnE X; 08-07-2004 at 06:42 PM.

  11. #11
    C++ n00bie :D
    Join Date
    Jul 2004
    Posts
    63
    Have you fixed this problem? I have used this method aswell, and as you can guess, Im having the same problem. These 2D arrays are annoying... Ive tried fixing it, but cant find the error. All I know is that its some form of runtime error, according to what the program said when it lagged and I read the first few words.

    "Error with Runtime"

    I wonder what the rest was, would probably help solve this

  12. #12
    Registered User
    Join Date
    Aug 2003
    Posts
    288
    well yeah i managed to get it working, thanks to the code Thantos provided, here it is if anyone is interested:

    Code:
    BYTE **bArray = NULL;
    
    bArray = new BYTE *[width];
    
    for (iLoop = 0; iLoop < width; iLoop++)
    	bArray[iLoop] = new BYTE[height];
    
    //and to delete:
    
    for (iLoop = 0; iLoop < width; iLoop++)
    	delete[] bArray[iLoop];
    
    delete[] bArray;

  13. #13
    C++ n00bie :D
    Join Date
    Jul 2004
    Posts
    63
    I meant did you fix the instant close thing, and if it was fixed with that, gotta do more work with mine

    Oh and, I caught a bit more of that error, only the first line, not sure of last line.

    "Error with runtime causing it to terminate in an unusual way."

  14. #14
    Registered User
    Join Date
    Aug 2003
    Posts
    470
    Your use of memset looks broken to me beucase you are taking the address bletter. Instead of using 2-d arrays, use the 1-d array. DWORD letter[width * height]. Becuase your algorithm to read does so sequentially, you can do so with a 1-nested loop.

    Writing your loops in column major form is bad practice in C++ and could slow down the program because the memory accesses are not sequential. Instead, do
    Code:
    for (int i = 0; i < height; ++i) {
         for (int j = 0; j < width; ++j) {
                letter[i][j] = ....///
         }
    }
    With using the 1-d array, however, you could just write it like
    Code:
    for (int i = 0; i < width * height; ++i)  {
           letter[i] = .....//
    }
    This will be probably faster because you will only use one dynamic allocation. Individual access into the array should probably be done with inline functions . For instance, you could write code similar to this
    inline void set_pixel(int x, int y, val)
    {
    letter[x + y * width] = val;
    }
    [/code]

  15. #15
    C++ n00bie :D
    Join Date
    Jul 2004
    Posts
    63
    That might help him, but not me
    My code uses a 2D array for storing data from a file, but the first 2 digits of the file tell it what the dimentions are, and then I make Dynamic Array for the data. Only problem is the same as his, it closes just as it opens. Mine just loads it normaly though, so I dont know what could be wrong. Heres Ill post some code:

    Code:
    //constructor
    testclass::testclass(char *filename) {
      dat_filename=new char[50];
      setfile(filename);
      setsize();
      ary_base=new int *[dat_length];
      for (int a=0; a<dat_length; a++) {
        ary_base[a]=new int[dat_width];
      }
    }//Constructor
    
    //in loadfile func
    void testclass::loadfile() {
      int x, y;
      std::ifstream load(dat_filename);
      for (x=0; x<dat_length; x++) {
        for (y=0; y<dat_width; y++) {
          load>>ary_base[x][y];
        }
      }
      load.close();
    }//testclass loadfile func
    And of course the deconstructor deletes the array, but the array doesnt work anyways... The program just closes near the start, while declaring the array Any tips? Did I mess up the declaring of the array?

    EDIT: LOL I got the rest of the error message:

    "Please contact the development team of this product"

    My question is, what do I ask him?
    Last edited by LloydUzari; 08-09-2004 at 04:05 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Creating and freeing dynamic arrays
    By circuitbreaker in forum C++ Programming
    Replies: 8
    Last Post: 02-18-2008, 11:18 AM
  2. Replies: 16
    Last Post: 01-01-2008, 04:07 PM
  3. Dynamic two dimensional arrays
    By ThWolf in forum C++ Programming
    Replies: 14
    Last Post: 08-30-2006, 02:28 PM
  4. processing dynamic arrays
    By Mario F. in forum C++ Programming
    Replies: 9
    Last Post: 06-04-2006, 11:32 AM
  5. Dynamic (Numeric) Arrays
    By DavidB in forum C++ Programming
    Replies: 5
    Last Post: 05-03-2006, 07:34 PM