如何在C中迭代遍历动态的矩形矩阵?

huangapple go评论61阅读模式
英文:

How to iterate through a dynamic, rectangular matrix in C?

问题

Sure, here's the translated code portion you requested:

我需要在C语言中使用动态内存中的指针创建一个矩阵,填充它们以随机数,然后打印出来。

这是大学作业的一部分(我必须为矩阵编写一整套函数),但是就帖子的目的而言,我认为我成功地找到并隔离了有问题的部分。以下是代码:

```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); //声明和分配矩阵的动态内存

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

    //生成矩阵的随机数:
    srand(time(NULL));

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

    //打印矩阵:
    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");

    //销毁矩阵
    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)(即 matrix[0][2]= 无法访问地址为 0xabababababababab 的内存

起初,我怀疑在为矩阵分配内存时出现了问题,但正如我所说,当矩阵是正方形时,它运行得很好,所以我真的不知道问题出在哪里。我知道StackOverflow社区不喜欢有人发布“我不知道我做错了什么,请帮助”的问题,但我确实花了很长时间尝试,无法找到问题的根本原因。请有人能够为我解答一下?


<details>
<summary>英文:</summary>
I have to create a matrix with pointers in dynamic memory in C, fill it with random numbers then print it.
This is part of a larger assignment from college (I had to do a whole library of functions for matrixes) but for the purposes of the post, I think I managed to track down and isolate the problematic bits. Here&#39;s the code:

#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&lt;rows;i++)
*(matrix+i) = malloc(sizeof(int) * cols);
//generating random numbers for the matrix:
srand(time(NULL));
for(int i=0;i&lt;rows;i++)
for(int j=0;j&lt;cols;j++)
*(*(matrix+j)+i) = rand() % 20;
//printing matrix:
printf(&quot;{\t&quot;);
for(int i=0;i&lt;rows;i++)
{
int j;
if(i&gt;0)
printf(&quot;\t&quot;);
printf(&quot;{\t&quot;);
for(j=0;j&lt;cols;j++)
printf(&quot;%d\t&quot;,*(*(matrix + j) + i));
printf(&quot;}&quot;);
if(i&lt;rows-1)
printf(&quot;\n&quot;);
}
printf(&quot;\t}\n\n&quot;);
//destroying the matrix
for(int i=0;i&lt;rows;i++)
free(matrix[i]);
free(matrix);
matrix = NULL;
return 0;

}


The debugger stops here:
`*(*(matrix+j)+i) = rand() % 20;`
Apparently, when trying to generate a random number for the first column of the second row (i.e. when it first changes rows) the debugger &quot;cannot access memory&quot; for that position, then the program crashes.
I tried changing the amount of rows and columns and I found it only crashes when row size is less than column size, which is weird because when it&#39;s equal or more, it works just fine.
I&#39;m trying with 2 rows by 3 columns. Expectation:

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


What actually happens:
`Process returned -1073741819 (0xC0000005)`
Values of the variables when the debugger stops (at generating random numbers):

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


At first I suspected I messed up when allocating memory for the matrix, but as I said when the matrix is square it does work fine, so I really don&#39;t know what&#39;s the issue here. I know the stackOverflow community doesn&#39;t like when someone posts &quot;I don&#39;t know what I did wrong please help&quot; kind of thing but I&#39;ve really been a long time trying and couldn&#39;t get to the root of the problem.
Can someone please shed some light on this for me?
</details>
# 答案1
**得分**: 2
These nested for loops contain a bug
这些嵌套的for循环包含一个错误
```c
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++)
*(*(matrix+i)+j) = rand() % 20;

这个指针matrix指向一个指针数组,这些指针又指向"rows"。所以表达式matrix + i指向第i行。然而,你却使用了索引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 )

为了引起你对下标操作符的兴趣,研究一下这些等价表达式,用来访问一个声明为

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 ) ]
英文:

These nested for loops contain a bug

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

The pointer matrix points to an array of pointers that in turn point to "rows". So the expression matrix + i points to the i-th "row". However instead you are using the index j.

That is you need to write

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

instead of

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

Otherwise when the value of cols is greater than the value of rows the expression matrix + j can access memory outside the allocated array of pointers (rows).

The same problem exists in this call of printf

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

where you have to write

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

That is you need actually to access an element matrix[i][j]. This expression may be rewritten like

( *( matrix + i ) )[j]

that in turn may be rewritten like

*( *( matrix + i ) + j )

Or in other way it may be rewritten like

*( matrix[i] + j )

and then

*( *( matrix + i ) + j )

To raise your interest to the subscript operator investigate these equivalent expressions to access elements of a two-dimensional array declared for example like

T a[M][N];

The expressions are

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 ) ]

huangapple
  • 本文由 发表于 2023年4月19日 16:20:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76052217.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定