【问题标题】:Windows has triggered a breakpoint - C languageWindows已触发断点-C语言
【发布时间】:2013-03-20 01:35:49
【问题描述】:

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

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

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;
}

【问题讨论】:

  • 能否也包括程序退出前命令行打印的内容?
  • 对我来说,您的代码(某种)无论如何都能正常工作,这不仅仅是一个奇迹。您为行分配了许多指向您的列的指针,每个指针指向位于 any 内存位置的许多内存单元块,您的 C 库的 malloc 实现认为合适,并期望通过类似的方法到达正确的位置rowpointer + i*row + column?该指针可能指向任何地方,但不指向正确的存储单元。顺便说一句:您甚至忘记释放矩阵分配函数中分配的所有列块。

标签: c malloc heap-memory breakpoints


【解决方案1】:

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

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 大小的数组使用更多的内存,前提是所有行都已分配。如果您有一些逻辑试图让空行未分配,您可以获得更好的内存性能,但它只会对我认为超出您分配范围的大型稀疏矩阵有益。

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

【讨论】:

  • 非常感谢您,您的回答对我帮助很大,我的代码现在正在运行,我也从中学到了东西。谢谢!
【解决方案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);
}

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

【讨论】:

  • 我要投票赞成你提到释放内存。那是我忘记做的部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-16
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多