#c #memory
#c #память
Вопрос:
Я пытаюсь динамически выделить 2D-массив INT в C, чтобы вернуть транспонированную матрицу, я провел несколько исследований по этой теме, и это должно работать таким образом, однако я продолжаю бороться с программой.
Теперь я пробовал это разными способами (смещение, арифметика указателей), но не нашел решения проблемы.
Я либо получаю мусорные значения, либо программа выходит из строя (ошибка seg отсутствует, сбой кода ошибки).
Я также ищу подходящую версию для выделения памяти, я видел несколько версий в stackoverflow, ту, которую я бы предпочел использовать, — это выделение пространства указателей и последующего целочисленного пространства (то, которое я пытаюсь использовать в примере ниже).
// Convert a matrix to it's transposed version. Returns a two dimensional array (pointer)
int **getTransposedMatrix(int *matrix, int dimension_h, int dimension_w){
int **transposedMatrix = (int **) malloc(dimension_w * sizeof(int*));
for(int row=0; row<dimension_w; row ){
transposedMatrix[row] = (int*) malloc(dimension_w * sizeof(int));
}
for(int row=0; row<dimension_h; row ){
for(int column=0; column<dimension_w; column ){
transposedMatrix[column][row] = *(matrix row * dimension_w column);
printf("%d ", transposedMatrix (row * dimension_w column));
}
printf("n");
}
return **transposedMatrix;
}
Я ценю любую помощь 🙂
Комментарии:
1. При распределении вы используете
dimension_w
для распределения оба измерения. Одно измерение должно бытьdimension_h
2. Это потому, что он должен возвращать транспонированную матрицу, хотя и пробовал это.
3.Понимание
int**
не имеет абсолютно никакого отношения к какому-либо массиву или 2D-массиву. Это просто указатель на указательint
. (это один указатель, который указывает на блок указателей) Для каждого из указателей в блоке вы можете назначить адрес блока, содержащего несколькоint
значений, для имитации 2D-массива.4. Если транспонировано, должно ли это быть
transposedMatrix[row] = (int*) malloc(dimension_h * sizeof(int));
, напримерw
, строки поh
столбцам?5. Оператор return неверен
return **transposedMatrix;
, он возвращает элемент в верхнем левом углу.
Ответ №1:
Я бы не стал беспокоиться о «2D-массиве», таком как тот, который вы настраиваете, где вы выделяете строки отдельно. Ниже приведена моя версия, которая использует один массив и соответственно вычисляет в нем смещения.
int *getTransposedMatrix(int *matrix, int dimension_w, int dimension_h)
{
int *transposed = malloc(dimension_w * dimension_h * sizeof(int));
for (int row = 0; row < dimension_h; row ) {
for (int col = 0; col < dimension_w; col ) {
transposed[col * dimension_h row] = matrix[row * dimension_w col];
}
}
return transposed;
}
Комментарии:
1. Спасибо за вашу помощь 🙂 Я бы предпочел иметь решение для отдельного выделения, я знаю, как сделать сольный указатель 🙂
2. В этом случае ваш исходный код верен, но просто измените оператор return на:
return transposedMatrix;
. Однако я должен отметить, что, если вы не работаете с очень большими матрицами и вам не нужно много эффективно перемещать строки, этот способ выделения пространства не имеет смысла. РЕДАКТИРОВАТЬ: И вам не нужно приводитьmalloc()
. EDIT2: и ваш оператор печати должен быть просто:printf("%d", transposedMatrix[column][row]);
3. Большое вам спасибо за вашу помощь @vmt 🙂 Я обычно выделяю свои выделения памяти, я думаю, что это хорошая практика, также синтаксис [column] [row] работает только при работе с таким распределением, верно? Я не уверен, но я обязательно изучу арифметику указателей с использованием скобок еще раз, еще раз спасибо! 🙂
4. когда вы приводите его к an
int**
, откладывая один раз, вы получаетеint*
и дважды,int
. Кроме того, приведение ваших распределений в C совершенно не нужно, поскольку приведение fromvoid*
является неявным. Кроме того, это может скрыть тот факт, что вы, возможно, не включили stdlib.h из-за неявных объявлений. Неявные объявления больше не имеют возвращаемого типа int , который находится в >= c99 , но на практике компилятор выдает предупреждение. Даже за исключением всего этого, в целом это считается плохой практикой.