Thread: Syntax: 3D array of a class

  1. #1
    Registered User
    Join Date
    Jun 2007
    Posts
    30

    Syntax: 3D array of a class

    Say I have a class:
    Code:
    class foo()
    {
      public: 
      foo(int n){
        x=n;
      }
    
       private:
       int x;   
    
    }
    How could I declare a 3D array of the class and use the constructor?
    i.e., if I am successful and cout the value of fooInstance[0][0][0].x, it will show "n" as the output.

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    That's not the proper syntax for declaring a class. Use
    Code:
    class foo {
    not
    Code:
    class foo() {
    You'd declare a 3D array of foo like you'd declare a 3D array of ints, like this:
    Code:
    foo fooInstance[x][y][z];
    [edit] To initialize such a variable, use
    Code:
    #include <iostream>
    
    class foo {
    private:
        int x;
    public:
        foo(int n) : x(n) {}
    };
    
    int main() {
        foo fooInstance[2][2][2] = {
            {
                {0, 1},
                {2, 3}
            },
            {
                {4, 5},
                {6, 7}
            }
        };
    }
    Is that what you meant? [/edit]
    Last edited by dwks; 07-04-2007 at 03:31 PM.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Registered User
    Join Date
    Jun 2007
    Posts
    30
    Thanks.

    I should be more specific; I also want to use the memory in the heap by using the new operator to declare the 3D array and instantiate it using the constructor.

    How may I do that?

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You can either use this (which requires a default constructor and knowledge of the y and z sizes):
    Code:
    #include <iostream>
    
    class foo {
    private:
        int x;
    public:
        foo() : x(0) {}
        foo(int n) : x(n) {}
    };
    
    int main() {
        foo (*fooInstance)[2][2] = new foo[2][2][2];
        
        delete [] fooInstance;
        
        return 0;
    }
    Or something like this, which still requires a default constructor, but lets you choose every size dynamically:
    Code:
    #include <iostream>
    
    class foo {
    private:
        int x;
    public:
        foo() : x(0) {}
        foo(int n) : x(n) {}
    };
    
    int main() {
        foo ***fooInstance = new foo**[2];
        
        for(int x = 0; x < 2; x ++) {
            fooInstance[x] = new foo*[2];
            for(int y = 0; y < 2; y ++) {
                fooInstance[x][y] = new foo[2];
            }
        }
        
        for(int x = 0; x < 2; x ++) {
            delete [] fooInstance[x];
            for(int y = 0; y < 2; y ++) {
                delete [] fooInstance;
            }
        }
        delete [] fooInstance;
        
        return 0;
    }
    You can't initialize arrays in new statements:
    Code:
    12 C:\path\foo.cpp ISO C++ forbids initialization in array new
    But you can do this:
    Code:
    int *x = new int(2);
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #5
    Registered User
    Join Date
    Jun 2007
    Posts
    30
    Thanks.

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    How silly can you get? The delete statements in my previous post are wrong -- I'm deleting before the for loops, whereas it should be after. It should be
    Code:
    #include <iostream>
    
    class foo {
    private:
        int x;
    public:
        foo() : x(0) {}
        foo(int n) : x(n) {}
    };
    
    int main() {
        foo ***fooInstance = new foo**[2];
        
        for(int x = 0; x < 2; x ++) {
            fooInstance[x] = new foo*[2];
            for(int y = 0; y < 2; y ++) {
                fooInstance[x][y] = new foo[2];
            }
        }
        
        for(int x = 0; x < 2; x ++) {
            for(int y = 0; y < 2; y ++) {
                delete [] fooInstance[x][y];
            }
            delete [] fooInstance[x];
        }
        delete [] fooInstance;
        
        return 0;
    }
    And here's the code you were looking for, that actually answers your question.
    Code:
    #include <iostream>
    
    class foo {
    private:
        int x;
    public:
        foo(int n) : x(n) {}
    };
    
    int main() {
        foo ****fooInstance = new foo***[2];
        
        for(int x = 0; x < 2; x ++) {
            fooInstance[x] = new foo**[2];
            for(int y = 0; y < 2; y ++) {
                fooInstance[x][y] = new foo*[2];
                for(int z = 0; z < 2; z ++) {
                    fooInstance[x][y][z] = new foo(x*2 + y*2 + z);
                }
            }
        }
        
        for(int x = 0; x < 2; x ++) {
            for(int y = 0; y < 2; y ++) {
                for(int z = 0; z < 2; z ++) {
                    delete fooInstance[x][y][z];
                }
                delete [] fooInstance[x][y];
            }
            delete [] fooInstance[x];
        }
        delete [] fooInstance;
        
        return 0;
    }
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  7. #7
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Meanwhile, despite all dwks effort (sorry mate. You are still the best) my advice to you, cybernike, is don't declare a three-dimensional array or bigger if you can avoid it.

    Being this a C++ forum, and especially because you want allocated memory, I would go to the extent of advising a three-dimensional std::vector, properly typedefed.

    Code:
    typedef std::vector< std::vector< std::vector<int> > > vector3D;
    But, probably a single dimension vector will make your life much easier. You will have to code for dimension boundaries inside the single-dimension vector. But it is probably more manageable than to try to read your code on a 3D array one week after you write it.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  8. #8
    Registered User
    Join Date
    Jun 2007
    Posts
    30
    Quote Originally Posted by Mario F. View Post
    Meanwhile, despite all dwks effort (sorry mate. You are still the best) my advice to you, cybernike, is don't declare a three-dimensional array or bigger if you can avoid it.

    Being this a C++ forum, and especially because you want allocated memory, I would go to the extent of advising a three-dimensional std::vector, properly typedefed.

    Code:
    typedef std::vector< std::vector< std::vector<int> > > vector3D;
    But, probably a single dimension vector will make your life much easier. You will have to code for dimension boundaries inside the single-dimension vector. But it is probably more manageable than to try to read your code on a 3D array one week after you write it.
    What if I ever need more than 4294967295 (max of unsighed long int) elements in an array?
    My compiler wouldn't recognize an integer larger than 4294967295.

  9. #9
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    hmm... you say you have a class storing an int. I'm assuming 32 bits per int on your system. You say you need to store more than 4 trillion copies (I hope its copies!) of this class in an array?

    Don't mind me asking. Just checking. Because 4294967295 x 32bits = 16 gigabytes of allocated memory. Are you sure you need to do that?

    The thing is that, if memory serves me right, you are somehow limited in the amount of memory an array can hold. I'm pretty sure I've read that somewhere. Someone here will know better.

    But still declaring it 3D won't change a thing, because there's no such thing as multi-dimensional arrays in C++. They are there for our convenience. They are still treated as a single dimension array by the compiler. So, you are still limited to size_t for the total number of elements.

    If you really need it, you can declare another array as an extension of the first.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  10. #10
    Registered User
    Join Date
    Jun 2007
    Posts
    30
    Quote Originally Posted by Mario F. View Post
    hmm... you say you have a class storing an int. I'm assuming 32 bits per int on your system. You say you need to store more than 4 trillion copies (I hope its copies!) of this class in an array?

    Don't mind me asking. Just checking. Because 4294967295 x 32bits = 16 gigabytes of allocated memory. Are you sure you need to do that?

    The thing is that, if memory serves me right, you are somehow limited in the amount of memory an array can hold. I'm pretty sure I've read that somewhere. Someone here will know better.

    But still declaring it 3D won't change a thing, because there's no such thing as multi-dimensional arrays in C++. They are there for our convenience. They are still treated as a single dimension array by the compiler. So, you are still limited to size_t for the total number of elements.

    If you really need it, you can declare another array as an extension of the first.
    For now, I don't need 4294967295 elements for a class or data type. The question was hypothetical. I know declaring a 3D array does not change the memory usage. What I was trying to say is the following:
    Say I need to store 10,000,000,000 integers in an array, I am saying my compiler would complain int[10000000000] because it would not recognize '10,000,000,000', which is larger than the max of unsigned long. However, it would be able to recongize int[100000][100000], since it understands the number '100000'.

    I am trying to use different algorithms and, yes, the idea of 3D array of bools came up earlier from one of my posts. Even though other algorithms did save me much more memory usage than a 3D array of bools, the best alternative, courtesy by iMalc, is about 1/3 slower than the 3D array of bools for my application. I haven't given up yet. Probably, I can do some modifications to iMalc's multiway-trie to fit my application better.
    Last edited by cybernike; 07-04-2007 at 05:23 PM.

  11. #11
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    > For now, I don't need 4294967295 elements for a class or data type.

    I don't think you will ever need one. But you do mention some history behind this post that I'm not aware of. So I'll refrain from staying on that topic.

    > my compiler would complain int[10000000000] because it would not recognize '10,000,000,000', which is larger than the max of unsigned long.

    See below.

    > However, it would be able to recongize int[100000][100000], since it understands the number '100000'.

    Most probably it won't. That's what I was trying to tell you.

    You see, the number of elements an array can hold on your system is defined by the type size_t. This type is defined in <cstddef> and it is system-specific. It is said to be large enough to hold the maximum number of elements of an array. Or it's size if you will.

    This is an unsigned integral. On my system (win32) it is defined as an unsigned long int. So to effectively define an int array, for instance you should:

    int my_array[size_t];

    Meanwhile a 2d array is defined like this:

    int my_array[size_t_1][size_t_2];

    However those two dimensions are there for our convenience. size_t_1 and size_t_2 multiplied together must still not exceed size_t (which on my win32 system is defined as an unsigned long).

    Your compiler will probably just pick the above and instead declare your array as:

    int my_array[size_t_1 * size_t_2];

    EDIT: I'm unsure at this point. Someone might know better. Because what it does in fact is create an array of arrays. So each size_t_1 is an int array of size_t_2 dimensions.

    There is in fact no such thing in C++ as a multidimensional array. What you have is an array of arrays.

    So,

    int[100000][100000]

    still breaks on my compiler. I get a compile time error saying that the array is too big. 100,000 times 100,000 > size_t
    Last edited by Mario F.; 07-04-2007 at 06:51 PM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. deriving classes
    By l2u in forum C++ Programming
    Replies: 12
    Last Post: 01-15-2007, 05:01 PM
  3. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM
  4. array of class object
    By TomButcher in forum C++ Programming
    Replies: 5
    Last Post: 09-03-2005, 09:48 AM
  5. linked list inside array of structs- Syntax question
    By rasmith1955 in forum C Programming
    Replies: 14
    Last Post: 02-28-2005, 05:16 PM