如何在 C 语言中迭代一个动态的矩形矩阵?

问题描述 投票:0回答:1

我必须在 C 的动态内存中创建一个带有指针的矩阵,用随机数填充它然后打印它。

这是大学更大作业的一部分(我必须为矩阵做一个完整的函数库)但是为了这篇文章的目的,我想我设法找到并隔离了有问题的部分。这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>

int main()
{
    int rows = 2;
    int cols = 3;
    int **matrix = malloc(sizeof(int*) * rows); //declaring and allocating dynamic memory for the matrix

    for(int i=0;i<rows;i++)
        *(matrix+i) = malloc(sizeof(int) * cols);

    //generating random numbers for the matrix:
    srand(time(NULL));

    for(int i=0;i<rows;i++)
        for(int j=0;j<cols;j++)
            *(*(matrix+j)+i) = rand() % 20;

    //printing matrix:
    printf("{\t");
    for(int i=0;i<rows;i++)
    {
        int j;

        if(i>0)
            printf("\t");
        printf("{\t");

        for(j=0;j<cols;j++)
            printf("%d\t",*(*(matrix + j) + i));

        printf("}");
        if(i<rows-1)
            printf("\n");
    }
    printf("\t}\n\n");

    //destroying the matrix
    for(int i=0;i<rows;i++)
        free(matrix[i]);

    free(matrix);
    matrix = NULL;

    return 0;
}

调试器在这里停止:

*(*(matrix+j)+i) = rand() % 20;

显然,当尝试为第二行的第一列生成随机数时(即当它第一次更改行时),调试器“无法访问该位置的内存”,然后程序崩溃。

我尝试更改行和列的数量,我发现只有当行大小小于列大小时它才会崩溃,这很奇怪,因为当它等于或大于列大小时,它工作得很好。

我正在尝试 2 行 3 列。期望:

{       {       5       17      3       }
        {       1       8       11      }       }

实际发生的事情:

Process returned -1073741819 (0xC0000005)

调试器停止时变量的值(生成随机数):

i = 0
j = 2
**(matrix + 2) (aka matrix[0][2]) = Cannot access memory at address 0xabababababababab

起初我怀疑我在为矩阵分配内存时搞砸了,但正如我所说,当矩阵是正方形时它确实工作正常,所以我真的不知道这里有什么问题。我知道 stackOverflow 社区不喜欢有人发布“我不知道我做错了什么,请帮忙”之类的东西,但我真的已经尝试了很长时间,但无法找到问题的根源。

有人可以帮我解释一下吗?

c matrix dynamic-memory-allocation pointer-arithmetic pointer-to-pointer
1个回答
2
投票

这些嵌套的 for 循环包含一个错误

for(int i=0;i<rows;i++)
    for(int j=0;j<cols;j++)
        *(*(matrix+j)+i) = rand() % 20;

指针

matrix
指向一个指针数组,而这个指针数组又指向“行”。所以表达式
matrix + i
指向
i-th
“行”。但是,您使用的是索引
j
.

那是你需要写的

*(*(matrix+i)+j) = rand() % 20;

代替

*(*(matrix+j)+i) = rand() % 20;

否则,当

cols
的值大于
rows
的值时,表达式
matrix + j
可以访问分配的指针数组(行)之外的内存。

printf的这次调用也存在同样的问题

 printf("%d\t",*(*(matrix + j) + i));

你必须写的地方

 printf("%d\t",*(*(matrix + i) + j));

那是您实际上需要访问一个元素

matrix[i][j]
。这个表达式可以改写成

( *( matrix + i ) )[j]

反过来可以重写为

*( *( matrix + i ) + j )

或者以其他方式重写为

*( matrix[i] + j )

然后

*( *( matrix + i ) + j )

为了提高您对下标运算符的兴趣,研究这些等效表达式以访问声明为例如 like

的二维数组的元素
T a[M][N];

表情是

a[i][j]
i[a][j]
j[a[i]]
j[i[a]]
*( *( a + i ) + j )
*( a[i] + j )
*( i[a] + j )
( *( a + i ) )[j]
j[*( a + i ) ]
© www.soinside.com 2019 - 2024. All rights reserved.