Thread: 2D array, size unknown at compile time

  1. #1
    Registered User
    Join Date
    Oct 2009
    Posts
    5

    2D array, size unknown at compile time

    Hey all. I'm hoping you can help with an array problem.

    I need to create a 2D array with size decided by the user during execution. After its size has been chosen it will not alter during execution of the program.

    How would I go about coding that up in a sensible way? Or, should I just approach it a different way?

    Thanks

  2. #2
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Doesnt this work?
    Code:
    x = getX(); //get from user
    y= getY();
    Object[,]  a = new Object[x,y];

  3. #3
    Registered User
    Join Date
    Oct 2009
    Posts
    5
    Read but not forgotten. That code worked fine of course, but I'm stumbling when I get to needing to use a constructor. If the array - let's make it of myClass objects is an attribute of a class, I have it declared as

    Code:
    // attribute declaration
    myClass[,] myArray;
    
    //ownerClassConstructor
    ownerClass(int height, int width, int somethingToGoInEachConstructor)
    {
       myArray = new myClass[height, width];
    }
    But I'm not really sure what to do with the int I want to go into the myClass constructor.
    Any thoughts?

  4. #4
    Registered User
    Join Date
    Oct 2009
    Posts
    5
    I've been doing some digging around and I wonder if I can now say

    Code:
    foreach (myClass instance in myArray){
       instance = new myClass(somethingToGoInEachConstructor);
    }
    What do you think?

  5. #5
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Why would the array size matter in C#? That's a huge benefit of C# array's - the size is handled and managed by the object and not by the program.

  6. #6
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    somethingToGoInEachConstructor
    use some static var that will be initialized using some static property before creating any instance of the class?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I guess my point is if you only add X number of items to the array and the array can handle a theoretical infinite number of items there isn't a need to maintain it's size in a variable. As well if you do store the size it is possible that the actual size of the array and the stored size could get out of sync. You can query the size of the array in C#. Storing the size is asking for trouble later. If you always query the array for it's size then you will never be incorrect.

  8. #8
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Quote Originally Posted by gah_ribaldi View Post
    Hey all. I'm hoping you can help with an array problem.

    I need to create a 2D array with size decided by the user during execution. After its size has been chosen it will not alter during execution of the program.

    How would I go about coding that up in a sensible way? Or, should I just approach it a different way?

    Thanks
    I'm unsure as to some of the answers of this thread. Maybe I'm not reading your question right. But my answer has little to do with some of them. No need for static vars, for instance.

    To create a fixed size array in C#, use the Array class. Other than the fact these arrays memory are still internally managed, their semantics are otherwise identical to C and C++ bult-in array types. You set the size at construction time and there's no changing it.

    To create dynamically allocated arrays, you use either the ArrayList class, or more correctly the List<T> generic type, introduced in version 2.0 of the .Net Framework.

    After its size has been chosen it will not alter during execution of the program.
    For this to be achieved, all you need to do is to create a class to hold your ArrayList or List<T> object. Your class will allow a size for the array to be set once through a simple algorithm:

    Code:
    class myClass
    {
    
        private ArrayList myArray_;
    
        private int size_;
        private bool size_set = false;
    
        public int Size
        {
            get { return size_; }
            set
            { 
                if (!size_set) size = value_;
                size_set = true;
            }
        }
    }
    I'll leave to you the study of how you expose the array inside that class and disallow any further Add operations once the size is reached. Show some code and we will work out the details.
    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.

  9. #9
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Yes. Perhaps I was confusing C# Array with ArrayList. Thanks for the correction Mario. This is why I only code in C# when I absolutely have to. I pretty much suck at it compared to some.

  10. #10
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Yet my answer is not the best depending on what the OP really wants to achieve. It's not very clear. But in any case wrapping the array inside a class seems the most extensible approach.

    ...

    For one there's the question of whether ArrayList is or not the best option. I was being lenient and didn't feel like getting into much detail at 5am, which is when I posted that Now that I've freshen up, let's see...

    ArrayList rarely is a good option since 2.0. The one big problem is it doesn't enforce strong typing. Once I define an ArrayList object I can put anything in there:

    Code:
    ArrayList arr = new ArrayList();
    
    arr.Add(new int());
    arr.Add(new Car());
    arr.Add(Invoices);
    That's... ugh!

    Sure, since I'm wrapping it inside a class I can create the logic to make sure only objects of the same type are inserted. But then that's what the generic types are all about.

    Code:
    List<int> arr = new List<int>();
    
    arr.Add(new int());
    arr.Add(new Car()); // compile-time error
    List<T> is an implementation of the IList<T> interface -- both defined under System.Collections.Generic -- And is aimed at mimicking ArrayList functionality. The System.Collections.Generic namespace is pretty much akin to our C++ STL implementation.

    On the other hand, we can simply ignore these classes and go back to basics with the Array class. According to the OP the only requirement is that the size must be set only once. Well, that's pretty much what Array does

    ...

    So ArrayList (and the other non-generic containers under System.Collections) is something that should not be used. Either the generic types if we need dynamic allocation, or the base Array type if we only need a fixed size array.

    Other than that I would need more details from the OP. Simply put there may not even be a need for a wrapper class. It sure seems so:

    Quote Originally Posted by OP
    I've been doing some digging around and I wonder if I can now say

    Code:
    foreach (myClass instance in myArray){
       instance = new myClass(somethingToGoInEachConstructor);
    }
    What do you think?
    Sure, you can. The only thing you want to make sure is that myClass constructor(s) are defined. For instance:

    Code:
    Class Computer
    {
        private string brand_;
        private string model_;
        private long memory_;
    
        public Computer() { } // default constructor. Members are set to default values
    
        public Computer(string brand, string model, long memory)
        {  // custom constructor. All members are set to user defined values
            brand_ = brand;
            model_ = model;
            memory_ = memory;
        }
    }
    With that you can now create an array of Computer objects and populate it according to the constructors you have defined:

    Code:
    Computer[] myComputers = new Computer[4];
    
    myComputers[0] = new Computer() // new computer with default constructor;
    myComputers[1] = new Computer("HP", "Prolient", 4000000000); // new computer with user-defined constructor
    
    Computer dad_computer = new Computer();
    Computer mom_computer = new Computer("Toshiba", "Satellite", 3000000000);
    
    myComputers[2] = dad_computer; // computer added from existing object
    myComputers[3] = mom computer; // computer added from existing object
    Last edited by Mario F.; 12-04-2009 at 11:37 AM.
    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.

  11. #11
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Yes ArrayList is a huge trashbin - literally. I cannot believe they hyped C# as a strongly typed language and then threw in a garbage can container for everyone to use.

    Generics are much better and are more like C++ templates.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Allocating an array of unknown size?
    By scarlet00014 in forum C Programming
    Replies: 2
    Last Post: 09-27-2008, 09:53 AM
  2. Sending an email in C program
    By Moony in forum C Programming
    Replies: 28
    Last Post: 10-19-2006, 10:42 AM
  3. Class Template Trouble
    By pliang in forum C++ Programming
    Replies: 4
    Last Post: 04-21-2005, 04:15 AM
  4. Type and nontype parameters w/overloading
    By Mr_LJ in forum C++ Programming
    Replies: 3
    Last Post: 01-02-2004, 01:01 AM
  5. Replies: 11
    Last Post: 03-25-2003, 05:13 PM

Tags for this Thread