0

我被分配创建一个程序,该程序获取二维数组、行数和列数,然后返回转置矩阵并打印它,只使用指针算术,不允许 []。

我的代码运行良好。它确实打印了转置矩阵,但在那之后,我收到以下消息:

Windows 已在 First Assignment.exe 中触发断点。

这可能是由于堆损坏,这表明 First Assignment.exe 或其已加载的任何 DLL 中存在错误。

这也可能是由于用户在 First Assignment.exe 具有焦点时按 F12。

输出窗口可能有更多诊断信息。

谁能帮我这个?我不知道出了什么问题。这是我的代码:

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
int** allocate_matrix(int rows,int columns);
void print_matrix(int** mat1,int rows, int columns);
void scan_matrix(int** mat1,int rows, int columns);
int** transpose_matrix(int** mat1, int rows, int columns);
void main()
{
    int** mat1;
    int** trans_mat1;
    int rows,columns;
    printf("Enter the number of rows and columns you wish to see\n");
    printf("Rows:");
    scanf("%d",&rows);
    printf("Columns:");
    scanf("%d",&columns);
    mat1 = allocate_matrix(rows,columns);
    scan_matrix(mat1,rows,columns);
    printf("the matrix you entered is: \n");
    print_matrix(mat1,rows,columns);
    printf("The transposed matrix is:\n");
    trans_mat1 = transpose_matrix(mat1,rows,columns);
    print_matrix(trans_mat1,columns,rows);
    getch();
    free(mat1);
    free(trans_mat1);
}
int** allocate_matrix(int rows,int columns)
{
    int i;
    int** ptrmatrix;
    ptrmatrix = (int**)malloc(rows*sizeof(int*));
    for(i=0;i<rows;i++)
        *(ptrmatrix+i) = (int*)malloc(columns*sizeof(int));
    return ptrmatrix;
}
void print_matrix(int** mat1,int rows, int columns)
{
    int i,j;
    for(i=0;i<rows;i++)
    {
        for(j=0;j<columns;j++)
            printf("%d ",*(mat1+i*columns+j));
        printf("\n");
    }
}
void scan_matrix(int** mat1,int rows, int columns)
{
    int i,j;
    for(i=0;i<rows;i++)
    {
        printf("Enter %d values for row number %d\n",columns,i+1);
        for(j=0;j<columns;j++)
            scanf("%d",(mat1+i*columns+j));
    }
}
int** transpose_matrix(int** mat1,int rows,int columns)
{
    int i,j;
    int** trans_mat1;
    trans_mat1 = allocate_matrix(columns,rows);
    for(i=0;i<rows;i++)
        for(j=0;j<columns;j++)
            *(trans_mat1+(j*rows)+i)=*(mat1+(i*columns)+j);
    return trans_mat1;
}
4

2 回答 2

3

导致问题的指针算法中似乎存在错误。

printf("%d ",*(mat1+i*columns+j));

应该:

printf("%d ",*(*(mat1+i)+j));

您似乎误解了如何分配矩阵。通常在这些类型的分配中,您会将矩阵分配为 NxM 整数的单个数组,然后使用您最初使用的公式。

例子:

int rows = 7, cols = 9;
int* matrix = (int*) malloc(rows * cols * sizeof(int));

// Get 3rd row and 5th column value
int value = *(matrix + 3 * rows + 5);

但是你正在做的是分配一个指向整数数组的指针数组。每个整数数组都是代码中的一行。因此,您需要做的是首先访问指针数组中的正确指针(mat + i)(表示指向第 i 行数组的指针),获取指针值*(mat+i),然后访问正确的列值。这是您的示例的逐个播放:

int rows = 9, cols = 21;

// Allocate the array of pointers to rows
int** matrix = (int**) malloc(rows * sizeof(int*));

// Allocate each row as an array of values
for (int j = 0; j < rows; ++j)
{
    *(matrix + j) = (int*) malloc(cols * sizeof(int));
}

// Access the value at row 5, column 7
int* rowPtr = *(matrix + 5);
int value = *(rowPtr + 7);

编辑:其他建议

解除分配:@mikyra 的回答还建议在使用后解除分配您的阵列。我也推荐这个,但不会将它包含在我的答案中,因为他已经完成了他的工作。请给他功劳。

内存效率:分配额外的指针数组比使用单个 NxM 大小的数组使用更多的内存,前提是所有行都已分配。如果您有一些逻辑试图保留未分配的空行,您可以获得更好的内存性能,但这只会对我认为超出您分配范围的大型稀疏矩阵有益。

我个人更喜欢单数组方法,因为它更容易分配/解除分配和索引。

于 2013-03-20T02:01:21.217 回答
2

在决定不只是为矩阵运算分配行 x 列内存块时,您真的没有帮自己一个忙。特别是如果这是作为指针算术的初学者练习。

访问第 i 行和第 j 列中单元格值的正确表达式实际上是这个:

*((*(mat1 + i))+j)

使用以下更正版本,一切都应该按预期工作:

void print_matrix(int** mat1,int rows, int columns)
{
    int i,j;

    for(i=0;i<rows;i++)
    {
        for(j=0;j<columns;j++)
          /* this line has been changed */
          printf("%d ", *((*(mat1 + i))+j));
        printf("\n");
    }
}
void scan_matrix(int** mat1,int rows, int columns)
{
    int i,j;
    for(i=0;i<rows;i++)
    {
        printf("Enter %d values for row number %d\n",columns,i+1);
        for(j=0;j<columns;j++)
          /* this line has been changed */
          scanf("%d",(*(mat1+i))+j);
    }
}
int** transpose_matrix(int** mat1,int rows,int columns)
{
    int i,j;
    int** trans_mat1;
    trans_mat1 = allocate_matrix(columns,rows);

    for(i=0;i<rows;i++)
        for(j=0;j<columns;j++)
          /* this line has been changed */
          *((*(trans_mat1 + j))+i) = *((*(mat1 + i))+j);
    return trans_mat1;
}

尽管如此,您仍然缺乏释放矩阵消耗的所有内存的方法。你需要这样的东西:

void deallocate_matrix (void* mat, int rows) {
  while (rows--)
    free (*(mat + rows));
  free (mat);
}

真正释放所有分配的内存。

于 2013-03-20T02:19:00.747 回答