代码主要是由我的讲师给我的。忽略free2DF功能。问题是在外部循环的第二次迭代中发生总线错误并且程序终止,我不确定为什么。我试图给前2个矩阵赋值,然后按索引为第三个索引添加它们。任何解释或帮助将不胜感激。
#include <stdio.h>
#include<stdlib.h>
float **alloc2Df(int height, int width);
void free2DF(float **matr);
int main(void)
{
int height = 4, width = 4, i, j;
float **matr1, **matr2, **matr3;
matr1 = alloc2Df(height, width);
matr2 = alloc2Df(height, width);
matr3 = alloc2Df(height, width);
for(i = 0; i < width; i++)
{
printf("%d\n", i*width);
for(j = 0; j < height; j++)
{
**(matr1+(i*width)+j) = 1;
**(matr2+(i*width)+j) = 2;
**(matr3+(i*width)+j) = **(matr1+(i*width)+j) + **(matr2+(i*width)+j);
printf("%-5.1f", **(matr3+(i*width)+j));
}
printf("\n");
}
return 0;
}
float **alloc2Df( int height, int width )
{
int i;
int nelem;
float *p, **pp;
nelem = height * width;
p = (float*)calloc( nelem, sizeof(float) );
if( p == NULL )
return NULL;
pp = (float**)calloc( height, sizeof(float*) );
if( pp == NULL )
{
free(p);
return NULL;
}
for ( i=0; i<height; i++ )
pp[i] = p + i*width;
return pp;
}
void free2Df( float **matr )
{
if( matr != NULL ) free( (float*) *matr );
free((float**) matr);
return;
}
答案 0 :(得分:0)
**(matr1+(i*width)+j)
毫无意义。
alloc2Df(height, width)
会返回大小为m
的动态数组height
。每个元素m[i]
都是指向大小为float
的{{1}}数组的第一个元素的指针。 (特别考虑:所有width
指向同一个大m[i]
数组的不同块,但这对于元素访问并不重要。)
这是显示float
:
matr1 = alloc2Df(3, 4)
只要matr1
|
v
[ ]----------------------->[0.0]
[ ]-------- [0.0]
[ ]-- \ [0.0]
\ \ [0.0]
\ ------------->[0.0]
\ [0.0]
\ [0.0]
\ [0.0]
---------------->[0.0]
[0.0]
[0.0]
[0.0]
是i
(外部循环的第一次迭代),我们就只是访问0
(其中**(matr1 + j)
来自{{} 1}}到j
):
0
2
会生成指向第一个数组中某个元素的指针(如左上图所示)。用matr1 --------v
matr1 + 0 -->[ ]----------------------->[1.0] X
matr1 + 1 -->[ ]-------- [0.0]
matr1 + 2 -->[ ]-- \ [0.0]
\ \ [0.0]
\ ------------->[1.0] X
\ [0.0]
\ [0.0]
\ [0.0]
---------------->[1.0] X
[0.0]
[0.0]
[0.0]
取消引用它给了我们数组元素本身,这是另一个指针;取消引用(再次使用matr1 + j
)会将我们发送到右侧的*
之一(标记为*
)。
到目前为止一切都很好。
然而,在外环float
的第二次迭代中是X
。因此,我们从i
计算的指针为1
,matr1 + i*width + j
,matr1 + 4 + 0
(因为此示例中为matr1 + 4 + 1
,matr1 + 4 + 2
。
width = 4
有两件事突出:
height = 3
。这可能是逻辑中的一个错误。 (如果我们的示例有matr1 --------v
matr1 + 0 -->[ ]----------------------->[1.0]
matr1 + 1 -->[ ]-------- [0.0]
matr1 + 2 -->[ ]-- \ [0.0]
\ \ [0.0]
matr1 + 4 --> ? \ ------------->[1.0]
matr1 + 5 --> ? \ [0.0]
matr1 + 6 --> ? \ [0.0]
\ [0.0]
---------------->[1.0]
[0.0]
[0.0]
[0.0]
,这将留下一个&#34;负差距&#34 ;;即,不是跳过元素,而是两次访问相同的元素。)matr1 + 3
指向左侧数组的末尾。实际上,所有指针height > width
都指向了谁知道matr1 + 4
。我采用无效指针,取消引用它(matr1 + i*width + j
),然后将在内存中找到的任何值作为另一个指针再次解除引用(i > 0
)并不会感到惊讶,导致崩溃。 有一个简单的解决方法:
*
或者,如果您想手动使用*
:
matr1[j][i]
没有必要增加任何东西。在给定大型1D阵列的情况下,您不会尝试模拟对2D阵列的访问;你所拥有的是一个两级结构,其中第一级包含第二级数组中正确的预计算偏移。
*
(或*(*(matr1 + j) + i)
)是指向第二个数组中的右块的指针。将matr1[j]
(或*(matr1 + j)
)应用于该组合可为您提供块中正确的元素。