0

How to declare a 2D array in which the rows are dynamic but the rows length are fixed? Is there any way to do it without both row and rows length are dynamic?

P.S. I can't use STL containers or class string.

1

4 Answers 4

4

You can use std::vector and std::array for this.

std::vector is a dynamic-length array.

std::array is a fixed-length array, used as

array<int, 20> arr;
arr[10] = 42;
array<int, 20> anotherArr = arr; // copied here, as opposed to C arrays

int oldStyleArr[20];
oldStyleArr[10] = 42;
// int newStyleArr[20] = oldStyleArr; // error here

It is a convenient wrapper over the C-style array, and it provides value semantics and various conveniece methods like size().

So you can create array<vector<int>, 20> for an array of 20 dynamic vectors of ints or vector<array<int, 20>> for a dynamic vector of fixed-length arrays.

UPD: std::array works only with array bounds known at compile-time. If your array bounds are known only at runtime, you still can use std::vector's constructor from size and (optional) element:

int rowCount, columnCount;
cin >> rowCount >> columnCount;
using Row = vector<int>;

// create `vector` of `rowCount` rows,
// where each row is `vector` of `columnCount` ints
vector<Row> arr2d(rowCount, Row(columnCount));

However, that's not the most efficient solution because each row is allocated separately. You can solve this with a little wrapper over one-dimensional vector:

template<class T>
class Vector2D {
public:
  Vector2D(int rows, int cols)
    : data(rows*cols)
    , rows(rows)
    , cols(cols) {}

  int rowCount() const { return rows; }
  int columnCount() const { return cols; }

  T&       get(int r, int c)       { return data[r*cols + c]; }
  T const& get(int r, int c) const { return data[r*cols + c]; }

  void addRow() {
    data.resize(cols*(rows + 1));
  }

// ...

private:
  vector<T> data;
  int rows;
  int cols;
};
Sign up to request clarification or add additional context in comments.

2 Comments

This works if the width is known at compile type. But it won't work for a real 2D array with rows and columns only known at runtime
@phuclv Dynamic arrays like vectors will perfectly fit in this case
0

You can use std::vector for dynamic range arrays. You would want to instantiate a vector of arrays to achieve this.

2 Comments

you mean std::vector (without uppercase). I think you have to explain more for the OP, also given example
You are right, that was a bit short. Yuri already gave a more extensive answer so I won't duplicate it but I will try to do better next time.
0

What you are looking for is probably: std::vector<std::array<int, 20>> arr;

However, if STL containers are not an option you might need to implement the container yourself. A linked list is probably the easiest to implement.

Comments

0

Just declare a 1D array and calculate the index yourself like how compilers generate accesses to a multidimensional array. Each row has width items, so the [x][y] element will have the index x*width + y

template<typename T>
class twoD
{
    const int width;
    const int height;
    T* data;

    twoD(int w, int h) : width(w), height(h)
    {
        data = new T[width*height];
    }

    ~twoD()
    {
        delete[] data;
    }

    T& at(int x, int y)
    {
        return data[x*width + y];
    }

    T const& at(int x, int y) const
    {
        return data[x*width + y];
    }
}

twoD myArray(4, 8);
myArray.at(2, 3) = 5;
myArray.at(4, 5) = 6 - myArray.at(2, 3);

The same method can be used to access multidimensional arrays in any degree

1 Comment

@Strick it's only a very simple example and not a full-blown solution. I'm not solving everything in OP's likely homework

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.