Фактически, вручную освобождая каждый указатель, это правильный способ сделать это в C, поскольку, как писал Серж, в C. автоматического вызова деструктора не существует, однако вы можете сделать это вручную и довольно красиво, не прибегая к динамическому стеку или сборщику мусора, подобному решениям.что, по моему мнению, обычно было бы огромным излишним.Так что без дальнейших церемоний.
Назовите функцию создателя так, чтобы было ясно, что она выделяет память как create ... или allocate ... or new ... и not get.Давайте предположим создать / удалить номенклатуру здесь.Итак:
int* create_matrix(int size);
Примечание. Я использую int*
, а не int**
.Это более удобно, не требует, чтобы вы делали все выделения второго измерения, вы просто выделяете один массив размером n*n
.В памяти это одно и то же пространство.Однако вы можете придерживаться двух измерений, если вы предпочитаете.
Далее деструктор
void delete_matrix(int* matrix);
Теперь, когда у нас есть красивый синтаксис, мы модифицируем ваши прототипы операций.Вместо того, чтобы брать два массива и возвращать вновь выделенный, используйте первый аргумент.Ваша функция умножения, распределяющая данные, не годится, так как не интуитивно предполагать, что умножение распределяет новые данные, а не возвращает их по значению.Итак:
int* matmul_recursive(int* left, const int* right, int size);
Обратите внимание, что мы не будем изменять right
, следовательно, const.Мы будем изменять left
, следовательно, без констант.Теперь запишите умножение left
и right
и поместите результаты в left
.Отсутствие дополнительного распределения означает отсутствие утечек.Функция должна возвращать left
для удобства связанных вызовов.
Обратите внимание, что вы можете добавить int* create_matrix_copy(const int* source, int size);
для клонирования матрицы.
Обратите также внимание, что вам обычно не нужны аргументыоперации после операций.Вас заинтересует полученная накопленная матрица.Посмотрите этот пример (используя имена ваших функций):
int* arg1 = create_matrix(n);
int* arg2 = create_matrix(n);
int* product1 = create_matrix(n);
int* product2 = create_matrix(n);
int* result = m_add(matmul_recursive(product1, arg1, n), matmul_recursive(product2, arg2, n), n);
delete_matrix(arg1);
delete_matrix(arg2);
delete_matrix(product2);
printf("%d", product1[0]);
printf("%d", result[0]); // result == product1
delete_matrix(product1);
Также используйте const
везде, где это применимо, т.е. вы не меняете значение аргумента, heplps избегает ошибок.Также рассмотрите возможность использования unsigned int
для размеров.
Также чаще, чем обычно, вы не будете выполнять много операций над одной матрицей, поэтому это будет более распространенным (например, 3D-преобразования):
int* result = create_matrix(n);
int* rotate = create_matrix(n);
int* translate = create_matrix(n);
int* scale = create_matrix(n);
matmul_recursive(matmul_recursive(matmul_recursive(result, rotate, n), translate, n), scale, n);
printf("%d", result[0]);
// Remember to delete all arguments.