|
| Zaita (2112) | |||||||||
| This is another topic we get asked quite a bit. - How do I do a 2D/3D Array? When I also started working with multi-dimensional arrays I found it hard to find the answers I wanted too. So I'll post up some info that will hopefully help other people. I'll go over both of the 2 major methods (Vector vs Pointer). Vector based multi-dimensional arrays Vectors are a STL container that allow you to store pretty much anything in them. When used correctly they can be very powerful containers. They provide an added benefit that they will automatically remove the memory they use when they go out of scope. This means that objects stored within a vector do not need to be de-allocated (but pointers to objects do). You can also do some interesting things with dynamic multi-dimensional arrays with vectors. For example, if you only allocate the first dimension, then use the .push_back() to add records to the 2nd dimension it's no longer a grid, but an array with a dynamically sized 2nd dimension (much like a street of buildings each with a different amount of floors). This functionality can be achieved using pointers, but is much harder to do. A simple 2D Array with vectors:
A 3D Array with vectors.
Pointer based multi-dimensional arrays Pointer based multi-dimensional arrays provide you with a more raw access to the objects. The benefits can be added speed and you can apply custom optimizations to them. Note: There are ways you can optimize this by combining the 2 dimensions into a single dimension (HEIGHTxWIDTH). I leave the discussion of this out, as it's a more advanced topic for people already familiar with this topic. A simple 2D Array:
A 3D Array:
One final thing to note. When creating dynamic arrays with your own object types, you cannot overload the constructor. The ISO standard forbids this, and you must initialize the values on the objects later. All objects allocated into arrays must utilize the default constructor. The above code snippets should compile on both Windows and Linux with no problems. Recommendations Unless your application has an extreme need to be highly optimized, and you are quite proficient at C++ memory management, you will want to use the vector based approach. This method is a lot easier to manage, especially if you are just learning C++. | |||||||||
| Mythios (753) | |
| Very nice Zaita, once you understand them they are more easier than you think. But you explanation here covers it quite well. So for those of you who don't I believe this will be helpful. Awesome work ;) Shame we cant ++rep; | |
| Mythios (753) | |
| You should possibly add how to pass 2d and 3d arrays to functions etc? Would be a good help for a lot of people as that question goes around a fair bit. | |
| cascade384 (34) | |
Would it be something like this?void function(double array[][WIDTH]) | |
| Zaita (2112) | |
| You can pass them by pointer. e.g void doSomethingWith2D(double **Array);or voud doSomethingWith2D(vector<vector<double> > &Array); | |
Last edited on | |
| Mythios (753) | |||
You can also pass them by reference
According to C++ Primer 4th Edition | |||
| cstrieder (56) | |||
| And how can a method return a vector? How can I do to pass matrix from method matrix_read to main?
| |||
| kempofighter (525) | |
@cstrieder: I wouldn't recommend returning the vector as it will cost you dearly. you'd have to build a vector within the function and return it by value resulting in a copy after building the vector. Multi-Dimensional arrays can get very large depending on their size and number of dimensions. I would recommend passing an inout parameter to the function as a reference and then filling it for the caller. The function would have a void return type. First, create a typedef for the type so that you don't have to retype so much.typedef std::vector<vector<double> > MatrixArrayType;Declare the function like so. Notice that you don't need to pass cols and lines parameters anymore because the caller could simply build the inout parameter to the correct initial size. Moreover, it is not good for Matrix_Read to assume things about the file. You need to take into consideration that the contents of the file could cause it to grow. void matrix_read(istream &iFile, MatrixArrayType& theMatrix); | |
| kempofighter (525) | ||||
| @zaita: I think that this is a nice article. I only have 2 minor critiques of it. First, the following statement is not entirely true. I see your point but it is worded incorrectly.
You can overload the constructor provided that you define the default constructor or provide a constructor that can be invoked without any arguments. Take a look at this example. It compiles just fine. The constructor has default values so a point can be constructed without any user supplied arguments.
The only other suggestion I had was to provide a 3rd section on non-dynamic multi-dimensional arrays. Perhaps the intent was to show how dynamic arrays are created but based on the title I thought it was about multi-dimensional arrays in general. They don't have to be dynamic at all. | ||||
| Polter (1) | |||
| Use the Boost Multidimensional Array Library: http://www.boost.org/doc/libs/1_39_0/libs/multi_array/doc/user.html Quoting synopsis: "The Boost Multidimensional Array Library provides a class template for multidimensional arrays, as well as semantically equivalent adaptors for arrays of contiguous data. The classes in this library implement a common interface, formalized as a generic programming concept. The interface design is in line with the precedent set by the C++ Standard Library containers. Boost MultiArray is a more efficient and convenient way to express N-dimensional arrays than existing alternatives (especially the std::vector<std::vector<...>> formulation of N-dimensional arrays). The arrays provided by the library may be accessed using the familiar syntax of native C++ arrays. Additional features, such as resizing, reshaping, and creating views are available (and described below). " Here's an example (from the same source):
| |||
Last edited on | |||
This topic is archived - New replies not allowed.
