Передача динамически размещенной матрицы в метод класса в C ++ - PullRequest
2 голосов
/ 22 марта 2012

Я пытаюсь создать динамически размещаемый двумерный массив с переменным размером, но я не знаю, почему, если я создам свое собственное постоянное значение, он не скомпилируется:

    const int oConstanta=N+1;

    int (*m)[oConstanta]=new int[oConstanta][oConstanta];

Но когда я используюнормальная константа, такая как 1000 в скобках, она успешно компилируется.

    const int oConstanta=N+1;

    int (*m)[1000]=new int[1000][1000];

Кто-нибудь знает причину этого?

PS: я знаю, что:

    int **m=new int*[oConstanta];

    for(i=1;i<=N;i++)
    {
        m[i]=new int[oConstanta];
        init(m[i]);
    }

решит мои проблемы, но я хочу узнать, почему мой прежний метод был плохой идеей.

Ответы [ 3 ]

1 голос
/ 22 марта 2012

Если N не является константой времени компиляции, oConstanta также не является константой времени компиляции.

Лучший способ создания двумерного массива в C ++ - использовать std::vectorstd::vector с, например, вот так:

#include <vector>

std::vector<std::vector<int> > m(N+1,  std::vector<int>(N+1, 0));
0 голосов
/ 22 марта 2012

Чтобы создать динамическую двумерную матрицу с непрерывными элементами и одним выделением:

std::vector<int> matrix(Rows*Columns);

Доступ к элементу в i -й строке и j -м столбце:

matrix[Columns*i + j] = 1;

Вы можете обернуть это все в классе. Вот очень простой пример:

struct Matrix {
    std::vector<int> m;
    size_t rows,columns;

    Matrix(size_t rows,size_t columns)
      : rows(rows)
      , columns(columns)
      , m(rows*columns)
    {}

    int &at(size_t i,size_t j) {
        return m.at(i*columns + j);
    }
};
0 голосов
/ 22 марта 2012

В конечном итоге причина в том, что вы не можете создавать статические массивы переменной длины.

В вашем коде вы пытаетесь создать статический массив динамических массивов, оба переменной длины.

Теперь статические массивы живут в стеке, а динамические массивы - в куче. В то время как управление памятью кучи «гибкое», стек отличается: компилятор должен иметь возможность определять размер каждого кадра в стеке. Это явно невозможно, если вы используете массив переменной длины. С другой стороны, если вы используете указатель, размер стекового кадра известен (указатель имеет известный размер), и все в порядке.

Если вы хотите попробовать, это должно хорошо скомпилироваться

int (*m)[1000]=new int[oConstanta][1000]

, поскольку это статический массив фиксированного размера, записи которого являются динамически размещаемыми массивами переменной длины (разрешено).

Вкратце: всякий раз, когда размер объекта неизвестен во время компиляции, этот объект не может быть в стеке, он должен выделяться динамически.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...