从函数返回一个二维动态数组

时间:2021-07-25 20:02:54

标签: c++ pointers

我需要一些关于从函数返回二维动态数组(矩阵)的帮助。该函数采用输入的矩阵并找到转置并返回矩阵。我的 main 获取用户想要的行数和列数,然后获取矩阵的条目。然后我调用我的函数并尝试将它保存在我创建的另一个动态矩阵中并尝试向矩阵求婚,但我在这样做时遇到了问题。我不知道如何保存结果矩阵。任何帮助都非常感谢。 你也可以检查我的解除分配过程是否正常?

刚刚意识到该程序适用于方阵,但如果行和列不同,您能指出我的错误吗?

int** transpose(int** arr, int rows, int cols)
{
    int** array1 = new int*[cols];

    for(int i =0; i < cols; i++)              
    {
        array1[i] = new int[rows];
    }

    for(int i = 0; i < rows; i++)
    {
        for(int j = 0; j < cols; j++)
        {
            array1[i][j] = arr[j][i];
        }
    }
    
    return array1;
for(int i =0; i < cols; i++)
{
    delete[] array1;
}
delete[] array1;
}

int main()
{
int rows, cols;
    cout << "Please enter the number of rows for the matrix: ";
    cin >> rows;
    cout << "Please enter the number of columns for the matrix: ";
    cin >> cols;

    int** array0 = new int*[rows];

    for(int i =0; i < rows; i++)
    {
        array0[i] = new int[cols];
    }

    // how to cin the elements for the matrix now
    //basicalliy it is thnesame as any 2d array
    for(int i = 0; i < rows; i++)
    {
        for(int j = 0; j < cols; j++)
        {
            cin >> array0[i][j];
        }
    }

    for(int i = 0; i < rows; i++)
    {
        for(int j = 0; j < cols; j++)
        {
            cout << array0[i][j] << " ";
        }
        cout << endl;
    }

    int** array2 = new int*[cols];
    for(int i = 0; i < cols; i++)
    {
        array2[i] = new int[cols];
    }
    array2 = transpose(array0, rows, cols);

    for(int i = 0; i < rows; i++)
    {
        for(int j = 0; j < cols; j++)
        {
            cout << array2[i][j] << " ";
        }
        cout << endl;
    }
    for(int i =0; i < cols; i++)
    {
        delete[] array2;
    }
    delete[] array2;

    for(int i =0; i < rows; i++)
    {
        delete[] array0;
    }
     delete[] array0;



    system("pause");
    return 0;
}

1 个答案:

答案 0 :(得分:1)

首先。在 C++ 中,强烈建议不要使用 newdelete 以及用于拥有内存的原始指针。正是这种容易出错的地方,甚至在许多产品中都禁止使用它。例如在汽车行业。

但是,我知道您的老师希望您这样做,以了解动态内存管理的底层机制。

所以,让我们将其用于您的学习目的。

基本上你的方法还不错。但是您正在混淆转置矩阵的行和列。这将导致越界运行时异常。

然后,在您的函数转置中,您试图删除刚刚分配的数组。但是你仍然需要在主函数中使用它。您想从函数中返回 array1。所以不要删除它。但是,因为您在删除操作之前移动了 return 语句,所以永远不会调用它。这是死代码。 return 之后的代码将不会被执行,因为您返回了函数。

无论如何。此处一定不能使用,删除即可。

另一个问题是您对变量的命名。如果您使用有意义的“会说话”的名字,那么您自己就已经看到了您的问题。

让我们看看你的代码:

#include <iostream>
using namespace std;
int** transpose(int** arr, int rows, int cols)
{
    int** array1 = new int* [cols];

    for (int i = 0; i < cols; i++)
    {
        array1[i] = new int[rows];
    }

    for (int i = 0; i < rows; i++) // *** Mixing of indices. Should be cols here
    {
        for (int j = 0; j < cols; j++) // *** Mixing of indices. Should be rows here
        {
            array1[i][j] = arr[j][i];
        }
    }

    return array1;

    // *** Dead code, will nver be called
    // And, must NOT be done in this function
    for (int i = 0; i < cols; i++)
    {
        delete[] array1;
    }
    delete[] array1;
}

int main()
{
    int rows, cols;
    cout << "Please enter the number of rows for the matrix: ";
    cin >> rows;
    cout << "Please enter the number of columns for the matrix: ";
    cin >> cols;

    int** array0 = new int* [rows];

    for (int i = 0; i < rows; i++)
    {
        array0[i] = new int[cols];
    }

    // how to cin the elements for the matrix now
    //basicalliy it is thnesame as any 2d array
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            cin >> array0[i][j];
        }
    }

    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            cout << array0[i][j] << " ";
        }
        cout << endl;
}

    // Completely unessecarry. Arry will be allocated in subfunction
    int** array2 = new int* [cols];
    for (int i = 0; i < cols; i++)
    {
        array2[i] = new int[cols];
    }


    array2 = transpose(array0, rows, cols);  // *** Simply define array2 as int**

    for (int i = 0; i < rows; i++) // *** Mixing of indices. Should be cols here
    {
        for (int j = 0; j < cols; j++) // *** Mixing of indices. Should be rows here
        {
            cout << array2[i][j] << " ";
        }
        cout << endl;
    }
    for (int i = 0; i < cols; i++)
    {
        delete[] array2; // You need to delete array2[i]
    }
    delete[] array2;

    for (int i = 0; i < rows; i++)
    {
        delete[] array0; // You need to delete array0[i]
    }
    delete[] array0;

    system("pause");
    return 0;
}

我在错误所在的地方添加了评论。

如果我们更正这些错误,那么我们将看到以下工作代码:

#include <iostream>

int** transpose(int** arr, int rows, int cols)
{
    int** array1 = new int* [cols];

    for (int i = 0; i < cols; i++)
    {
        array1[i] = new int[rows];
    }

    for (int i = 0; i < cols; i++)
    {
        for (int j = 0; j < rows; j++)
        {
            array1[i][j] = arr[j][i];
        }
    }

    return array1;
    for (int i = 0; i < cols; i++)
    {
        delete[] array1;
    }
    delete[] array1;
}

int main()
{
    int rows, cols;
    std::cout << "Please enter the number of rows for the matrix: ";
    std::cin >> rows;
    std::cout << "Please enter the number of columns for the matrix: ";
    std::cin >> cols;

    int** array0 = new int* [rows];

    for (int i = 0; i < rows; i++)
    {
        array0[i] = new int[cols];
    }

    // how to cin the elements for the matrix now
    //basicalliy it is thnesame as any 2d array
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            std::cin >> array0[i][j];
        }
    }

    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            std::cout << array0[i][j] << " ";
        }
        std::cout << std::endl;
    }
    /*
    int** array2 = new int* [cols];
    for (int i = 0; i < cols; i++)
    {
        array2[i] = new int[cols];
    }
    */

    int** array2 = transpose(array0, rows, cols);

    for (int i = 0; i < cols; i++)
    {
        for (int j = 0; j < rows; j++)
        {
            std::cout << array2[i][j] << " ";
        }
        std::cout << std::endl;
    }

    for (int i = 0; i < cols; i++)
    {
        delete[] array2[i];
    }
    delete[] array2;

    for (int i = 0; i < rows; i++)
    {
        delete[] array0[i];
    }
    delete[] array0;

    return 0;
}

现在是相同的代码。但具有更好的变量名称和注释。

这更容易理解。

#include <iostream>

// Function to transpose a given 2d array and return a new dynamically create transposed array
int** transpose2dArray(int** arrayToTranspose, unsigned int numberOfRowsOriginal, unsigned int numberOfColumnsOriginal)
{
    // Transposing means basically a swap of rows and columns
    unsigned int numberOfRowsTransposed = numberOfColumnsOriginal;
    unsigned int numberOfColumnsTransposed = numberOfRowsOriginal;

    // Allocate a new 2d array. But now, with new (transposed) dimensions
    int** arrayTransposed = new int* [numberOfRowsTransposed];
    for (unsigned int row = 0; row < numberOfRowsTransposed; ++row)
    {
        arrayTransposed[row] = new int[numberOfColumnsTransposed];
    }

    // Now do the transpose action. Simply exchange orws and columns
    for (unsigned int row = 0; row < numberOfRowsTransposed; ++row)
    {
        for (unsigned int col = 0; col < numberOfColumnsTransposed; ++col)
        {
            arrayTransposed[row][col] = arrayToTranspose[col][row];
        }
    }
    // And thats it. Return transposed array to caller of this function
    return arrayTransposed;
}

int main()
{
    // Get the numer of rows and coulmns for the array to transpose from the user
    unsigned int numberOfRows, numberOfColumns;
    std::cout << "Please enter the number of rows for the matrix: ";
    std::cin >> numberOfRows;
    std::cout << "\nPlease enter the number of columns for the matrix: ";
    std::cin >> numberOfColumns;

    // Allocate 2d array dynamically, based on user input
    int** array = new int* [numberOfRows];
    for (unsigned int row = 0; row < numberOfRows; ++row)
    {
        array[row] = new int[numberOfColumns];
    }
    // Read all values for the 2d array from the user
    for (unsigned int row = 0; row < numberOfRows; ++row)
    {
        for (unsigned int col = 0; col < numberOfColumns; ++col)
        {
            std::cin >> array[row][col];
        }
    }
    // Some debug output
    for (unsigned int row = 0; row < numberOfRows; ++row)
    {
        for (unsigned int col = 0; col < numberOfColumns; ++col)
        {
            std::cout << array[row][col] << " ";
        }
        std::cout << std::endl;
    }

    // Call the transpose function and get a new dynamically allocated 2d array
    int** arrayTransposed = transpose2dArray(array, numberOfRows, numberOfColumns);

    // Now we have a swapped number of rows and columns
    unsigned int numberOfRowsTransposed = numberOfColumns;
    unsigned int numberOfColumnsTransposed = numberOfRows;

    // Show the transposed output. Use other row and column numbers
    for (unsigned int row = 0; row < numberOfRowsTransposed; ++row)
    {
        for (unsigned int col = 0; col < numberOfColumnsTransposed; ++col)
        {
            std::cout << arrayTransposed[row][col] << " ";
        }
        std::cout << std::endl;
    }
    // And delete the dynamically allocated memory
    for (unsigned int row = 0; row < numberOfRowsTransposed; ++row)
    {
        delete[] arrayTransposed[row];
    }
    delete[] arrayTransposed;

    for (unsigned int row = 0; row < numberOfRows; ++row)
    {
        delete[] array[row];
    }
    delete[] array;

    return 0;
}
相关问题