0

2次元配列、行数、列数を取得し、転置された行列を返し、ポインター演算のみを使用して出力するプログラムを作成するという割り当てが与えられました。[]は許可されていません。

私のコードは完全に機能しています。確かに転置された行列を出力しますが、その後、次のメッセージが表示されます。

WindowsがFirstAssignment.exeでブレークポイントをトリガーしました。

これは、ヒープの破損が原因である可能性があります。これは、FirstAssignment.exeまたはロードされたDLLのバグを示しています。

これは、FirstAssignment.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 に答える