我正在做一个工作,在该工作中,我被要求串联两个用C ++动态分配的2D数组(矩阵)。给定矩阵A和矩阵B,必须将矩阵A更新为串联的新矩阵,并且必须销毁矩阵B。在执行连接本身的函数中,连接的数组将按预期方式进行打印,但是我遇到了分段错误。返回分段错误的函数是horzcat()函数。
#include <iostream>
#include <stdexcept>
#include <string>
#include "matrix_helper.h"
// no other includes are allowed
using std::cout, std::endl;
using std::invalid_argument;
using std::to_string;
using std::size_t;
using std::ostream;
/*
dynamically allocates a new rows x cols matrix
initialize all elements to 0
*/
Matrix create_matrix(size_t rows, size_t cols) {
int** MatrixA = new int*[rows];
for (int a = 0; a < rows; a++) {
MatrixA[a] = new int[cols];
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
MatrixA[i][j] = 0;
}
}
return MatrixA;
}
// overload to create square matrices
// initialize all elements to 0
Matrix create_matrix(size_t n) {
int** MatrixA = new int*[n];
for (int a = 0; a < n; a++) {
MatrixA[a] = new int[n];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
MatrixA[i][j] = 0;
}
}
return MatrixA;
}
/*
given matrices A, B
horizontally concatenate B onto A
updates and returns A, frees B */
**Matrix& horzcat(Matrix& A,
size_t& rows_A,
size_t& cols_A,
Matrix& B,
size_t& rows_B,
size_t& cols_B) {
if (rows_A != rows_B) {
throw invalid_argument("Non matching number of rows");
}
else {
size_t newCols = cols_A + cols_B;
//Matrix tempMatrix = create_matrix(rows_A, newCols);
// pointer to new matrix
Matrix tempMatrix = create_matrix(rows_A, newCols);
// filling new matrix
for (int i = 0; i < rows_A; i++) {
for (int j = 0; j < cols_A; j++) {
tempMatrix[i][j] = A[i][j];
}
for (int k = cols_A; k < newCols; k++) {
tempMatrix[i][k] = B[i][k - cols_A];
}
}
// delete A
for (int i = 0; i < rows_A; i++) {
delete [] A[i];
}
delete [] A;
cols_A = newCols;
Matrix A = create_matrix(rows_A, cols_A);
for (int a = 0; a < rows_A; a++) {
for (int b = 0; b < cols_A; b++) {
A[a][b] = tempMatrix[a][b];
}
}
delete [] B;
delete [] tempMatrix;
return A;
}
}**
int main() {
// A = [1 2 ; 3 4]
Matrix A = create_matrix(2);
size_t rows_A = 2;
size_t cols_A = 2;
A[0][0] = 1;
A[0][1] = 2;
A[1][0] = 3;
A[1][1] = 4;
print_matrix(A, rows_A, cols_A);
// B = [5 6 7 ; 8 9 10]
Matrix B = create_matrix(2,3);
size_t rows_B = 2;
size_t cols_B = 3;
B[0][0] = 5;
B[0][1] = 6;
B[0][2] = 7;
B[1][0] = 8;
B[1][1] = 9;
B[1][2] = 10;
print_matrix(B, rows_B, cols_B);
// horzcat(A, B)
print_matrix(horzcat(A, rows_A, cols_A, B, rows_B, cols_B), rows_A, cols_A);
// A
print_matrix(A, rows_A, cols_A);
// B
print_matrix(B, rows_B, cols_B);
// do you hear a leak?
return 0;
}
这里是添加的matrix_helper.h代码
// DO NOT CHANGE ANYTHING IN THIS FILE
// if you do, it could break the test cases
// it will be your fault
// you will lose points
// DO NOT CHANGE ANYTHING IN THIS FILE
#ifndef MATRIX_H
#define MATRIX_H
#include <cstddef>
#include <stdexcept>
#include <string>
#include <iostream>
#include <iomanip>
// no other includes are allowed
// typedef magic so that "Matrix" means "int**";
// if this confuses you, you can use "int**"" instead of "Matrix"
typedef int Value;
typedef Value* Row;
typedef Row* Matrix;
typedef const Value constValue;
typedef constValue* constRow;
typedef constRow const* constMatrix;
// length of n in characters
std::size_t get_width(int n) {
if (n < 0) {
return 1 + get_width(-n);
}
if (n < 10) {
return 1;
}
return 1 + get_width(n/10);
}
// pretty print a matrix with right-aligned columns
void print_matrix(constMatrix matrix, std::size_t rows, std::size_t cols, std::ostream& os=std::cout) {
// handle the empty matrix
if (rows == 0 || cols == 0) {
os << std::endl << "[]" << std::endl;
return;
}
// compute column widths
std::size_t* width = new std::size_t[cols]{0};
for (std::size_t col = 0; col < cols; ++col) {
for (std::size_t row = 0; row < rows; ++row) {
std::size_t digits = get_width(matrix[row][col]);
if (digits > width[col]) {
width[col] = digits;
}
}
}
// pretty print with right-aligned columns
os << std::endl;
for (std::size_t row = 0; row < rows; ++row) {
os << "|";
for (std::size_t col = 0; col < cols; ++col) {
os << " " << std::setw(width[col]) << matrix[row][col];
}
os << " |" << std::endl;
}
delete[] width;
}
#endif
您的horzcat
函数破坏了传递给它的A
矩阵。然后,它会创建一个新的矩阵,也称为A
(永远不要这样做!),这可能会使您感到困惑,认为它仍在操纵原始的A矩阵。
Matrix A = create_matrix(rows_A, cols_A);
这将创建一个称为Matrix
的new A
,该图像会遮盖原始图像。您想修改现有的。此时,您有两个都称为A
的矩阵-一个通过销毁的引用传递给您的矩阵,以及在此处创建的新矩阵。]
您想要:
A = create_matrix(rows_A, cols_A);
您的编译器应该给您有关阴影参数的警告。如果您不理it它,可耻的是您。如果没有,请学习如何使编译器发出警告或使用更好的编译器。
我希望这不是C ++类,因为用这种方法编码绝对没有任何借口。原始指针的行为不像普通值那样,并且极难使用。每当不需要它们时都应避免使用它们,并且在此绝对不需要它们。将它们隐藏在typedef
后面是无法防御的。