Код, показанный в вопросе, дает мою сборку Valgrind conniptions, потому что он неправильно использует нотацию указателя на матрицу.При автономном запуске (не в Valgrind) он работает, но выходная матрица не является транспонированной входной матрицей, поскольку к данным не был получен правильный доступ.Это пример фиктивного вывода, который я получаю.Вы можете видеть, что элементы с индексами 0,1 и 1,0 в матрице 'транспонирования' не связаны с элементами в исходной матрице.
1.24 2.64 0.17 0.49 22.25 4.30 0.71 1.12 1.03 2.31
1.39 7.18 0.40 0.44 4.30 0.17 0.62 12.67 0.34 9.10
2.85 0.69 3.50 1.58 0.77 0.04 0.26 0.79 0.24 1.59
16.00 0.14 0.12 0.56 1.68 0.08 0.69 0.13 2.51 1.74
5.50 0.96 0.45 1.00 0.00 0.84 0.97 0.40 2.14 0.67
2.00 0.14 1.84 0.88 1.26 0.21 0.70 0.30 1.74 0.60
2.04 1.00 0.35 0.12 0.00 0.65 1.21 0.18 0.52 9.70
1.19 1.08 0.88 1.71 0.88 0.21 1.74 0.70 0.44 1.23
1.38 0.69 0.12 0.14 4.18 3.17 0.06 7.10 8.00 1.52
0.16 6.07 0.81 0.49 0.14 1.37 4.00 0.93 0.98 1.48
Transpose:
1.24 1.24 2.64 0.17 0.49 22.25 4.30 0.71 1.12 1.03
-2.00 1.39 1.39 2.85 16.00 5.50 2.00 2.04 1.19 1.38
0.17 2.85 0.69 0.69 0.14 0.96 0.14 1.00 1.08 0.69
0.49 16.00 0.14 0.12 0.12 0.45 1.84 0.35 0.88 0.12
22.25 5.50 0.96 0.45 1.00 1.00 0.88 0.12 1.71 0.14
4.30 2.00 0.14 1.84 0.88 1.26 1.26 0.00 0.88 4.18
0.71 2.04 1.00 0.35 0.12 0.00 0.65 0.65 0.21 3.17
1.12 1.19 1.08 0.88 1.71 0.88 0.21 1.74 1.74 0.06
1.03 1.38 0.69 0.12 0.14 4.18 3.17 0.06 7.10 7.10
2.31 0.16 6.07 0.81 0.49 0.14 1.37 4.00 0.93 0.98
Приведенный ниже код работает для квадратных матриц.Разница в том, что указатель на матрицу разыменовывается до применения подписки ((*matrix)[i][j]
), а не после (*matrix[i][j]
).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define len 10
#define hi 10
void transpose(double (*matrix)[len][hi]);
int main(void)
{
srand(time(NULL));
double (*matrix)[len][hi] = (double (*)[len][hi])malloc(sizeof(double[len][hi]));
double delimo, delitel;
for (int i = 0; i < len; i++)
{
for (int j = 0; j < hi; j++)
{
delimo = rand() % (len * hi);
delitel = rand() % (len * hi);
(*matrix)[i][j] = delimo / ++delitel;
printf(" %5.2lf ", (*matrix)[i][j]);
}
puts("");
}
puts("Transpose: ");
transpose(matrix);
for (int i = 0; i < len; i++)
{
for (int j = 0; j < hi; j++)
{
printf(" %5.2lf ", (*matrix)[i][j]);
}
puts("");
}
free(matrix);
}
void transpose(double (*matrix)[len][hi])
{
double (*Tmatrix)[len][hi] = (double (*)[len][hi])malloc(sizeof(double[len][hi]));
for (int i = 0; i < len; i++)
{
for (int j = 0; j < hi; j++)
{
(*Tmatrix)[i][j] = (*matrix)[j][i];
}
}
for (int i = 0; i < len; i++)
{
for (int j = 0; j < hi; j++)
{
(*matrix)[i][j] = (*Tmatrix)[i][j];
}
}
free(Tmatrix);
}
Пример вывода:
0.98 0.90 0.16 0.08 0.48 1.71 0.53 0.24 2.28 1.79
0.73 0.36 2.00 3.27 0.29 1.25 19.40 1.60 0.56 0.00
3.00 10.50 1.81 1.56 1.11 0.78 1.53 0.71 1.27 0.93
2.10 0.56 2.34 1.48 0.81 2.16 0.47 0.16 7.62 0.91
0.93 2.48 0.15 0.71 1.09 0.73 0.58 0.48 1.13 0.99
0.59 0.72 8.75 2.19 61.00 1.41 2.08 0.83 0.65 0.16
0.42 1.13 0.85 1.00 3.00 0.55 0.33 1.67 0.44 0.69
0.08 1.17 0.25 0.92 1.04 0.17 1.77 1.95 0.50 0.90
2.28 0.35 0.41 1.27 0.80 3.36 0.29 0.13 3.88 0.39
0.64 0.50 0.40 0.15 0.45 0.78 0.31 1.48 1.50 1.06
Transpose:
0.98 0.73 3.00 2.10 0.93 0.59 0.42 0.08 2.28 0.64
0.90 0.36 10.50 0.56 2.48 0.72 1.13 1.17 0.35 0.50
0.16 2.00 1.81 2.34 0.15 8.75 0.85 0.25 0.41 0.40
0.08 3.27 1.56 1.48 0.71 2.19 1.00 0.92 1.27 0.15
0.48 0.29 1.11 0.81 1.09 61.00 3.00 1.04 0.80 0.45
1.71 1.25 0.78 2.16 0.73 1.41 0.55 0.17 3.36 0.78
0.53 19.40 1.53 0.47 0.58 2.08 0.33 1.77 0.29 0.31
0.24 1.60 0.71 0.16 0.48 0.83 1.67 1.95 0.13 1.48
2.28 0.56 1.27 7.62 1.13 0.65 0.44 0.50 3.88 1.50
1.79 0.00 0.93 0.91 0.99 0.16 0.69 0.90 0.39 1.06
Вы не можете транспонировать неквадратную матрицу на месте.Если в качестве входных данных используется матрица n
x m
, транспонирование представляет собой матрицу m
x n
.Вероятно, проще всего выделить матрицу транспонирования, в которой вы разместите нетранспонированную матрицу и передать обе матрицы функции транспонирования.Обратите внимание на использование *matrix
для передачи указателя на матрицу в качестве матрицы функции.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
void transpose(int rows, int cols, double matrix[rows][cols], double result[cols][rows]);
void print_matrix(const char *tag, int rows, int cols, double matrix[rows][cols]);
int main(void)
{
srand(time(NULL));
int cols = 10;
int rows = 8;
double (*matrix)[rows][cols] = malloc(sizeof(double[rows][cols]));
double (*result)[cols][rows] = malloc(sizeof(double[cols][rows]));
if (matrix == 0 || result == 0)
{
fprintf(stderr, "failed to allocate memory\n");
exit(EXIT_FAILURE);
}
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
double delimo = rand() % (rows * cols);
double delitel = rand() % (rows * cols) + 1;
(*matrix)[i][j] = delimo / delitel;
}
}
print_matrix("original", rows, cols, *matrix);
transpose(rows, cols, *matrix, *result);
print_matrix("transpose", cols, rows, *result);
free(matrix);
free(result);
return 0;
}
void print_matrix(const char *tag, int rows, int cols, double matrix[rows][cols])
{
printf("%s (%dx%d):\n", tag, rows, cols);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
printf(" %5.2f ", matrix[i][j]);
putchar('\n');
}
}
void transpose(int rows, int cols, double matrix[rows][cols], double result[cols][rows])
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
result[j][i] = matrix[i][j];
}
}
}
Пример вывода:
original (8x10):
0.84 0.92 0.18 1.97 4.54 31.00 1.59 0.11 0.35 0.07
0.96 3.19 1.00 4.86 3.25 3.50 2.65 1.07 0.24 0.77
6.00 0.13 0.40 1.04 0.99 0.88 1.24 0.67 3.07 12.00
1.89 0.48 0.72 0.55 0.26 0.64 0.55 0.09 0.30 0.98
0.51 0.86 0.85 0.33 1.44 0.89 2.38 2.21 0.27 2.12
6.40 1.71 2.83 1.61 0.76 0.13 0.81 1.48 1.13 0.51
0.79 0.69 0.57 1.10 1.00 1.31 0.68 1.95 1.42 0.46
0.00 0.43 1.64 0.88 1.03 0.14 0.35 1.78 0.86 2.82
transpose (10x8):
0.84 0.96 6.00 1.89 0.51 6.40 0.79 0.00
0.92 3.19 0.13 0.48 0.86 1.71 0.69 0.43
0.18 1.00 0.40 0.72 0.85 2.83 0.57 1.64
1.97 4.86 1.04 0.55 0.33 1.61 1.10 0.88
4.54 3.25 0.99 0.26 1.44 0.76 1.00 1.03
31.00 3.50 0.88 0.64 0.89 0.13 1.31 0.14
1.59 2.65 1.24 0.55 2.38 0.81 0.68 0.35
0.11 1.07 0.67 0.09 2.21 1.48 1.95 1.78
0.35 0.24 3.07 0.30 0.27 1.13 1.42 0.86
0.07 0.77 12.00 0.98 2.12 0.51 0.46 2.82
Valgrind дает обоим из них чистый счет здоровья.Исходный код заставил Valgrind сообщать о множестве ошибок, таких как:
==33404== Signal 11 being dropped from thread 0's queue
Мне пришлось убить этот запуск из другого окна терминала.