我被赋予了一个创建程序的任务,该程序获取一个二维数组,行数和列数,然后返回转置矩阵并打印它,仅使用指针算法,不允许[]。
我的代码工作正常。它确实打印了转置矩阵,但在此之后,我收到以下消息:
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;
}
答案 0 :(得分: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);
编辑: 其他建议
Dealocation: @ mikyra的回答还建议在使用后释放你的阵列。我也推荐这个,但不会在我的回答中包括它,因为他已经完成了他的工作。请相信它。
内存效率: 如果分配了所有行,则分配额外的指针数组比使用单个NxM大小的数组使用更多的内存。如果你有一些逻辑试图留下未分配的空行,你可以获得更好的内存性能,但它只对大型稀疏矩阵有益,我认为这超出了你的任务范围。
我个人更喜欢单阵列方法,因为它更容易分配/解除分配和索引。
答案 1 :(得分: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);
}
真正释放所有已分配的内存。