提问人:hhh3 提问时间:2/14/2023 最后编辑:Vlad from Moscowhhh3 更新时间:2/14/2023 访问量:76
为什么错位的 2D 数组的地址不是我所期望的?
Why are the addresses of malloced 2D array not what I expect?
问:
为了在 C 中为 2D 数组分配内存,我运行
double (*t)[2] = malloc(sizeof(*t)*4);
我预计这将分配 64 个字节(两个双精度大小的 4 倍)。也就是说,我预计 t[0] 和 t[1] 各有 4 个双打的空间。出于这个原因,我认为 t[0] 和 t[1] 的地址应该分隔 32 个字节。但是,我发现它们之间有 16 个字节的隔音(仅对应于两个双精度)。
printf("Address of t[0]: %p\n", t[0]); // Address of t[0]: 00C92490
printf("Address of t[1]: %p\n", t[1]); // Address of t[1]: 00C924A0
我在这里错过了什么?
答:
这似乎是这里的声明和分配中的误解。声明为数组,其中数组中的每个元素都是由两个元素组成的数组。然后,为 中的四个元素分配足够的空间。t
t
double
t
您的定义和分配等同于:
double t[4][2];
如果要创建包含两个元素的数组,其中每个元素都是一个动态分配的数组,则需要一个指针数组:
double *t[2] = { malloc(sizeof(*t[0]) * 4), NULL };
上面定义为一个由两个元素组成的数组,每个元素都是一个指向 的指针,你初始化第一个元素 () 以指向一个由四个元素组成的数组,将第二个元素 () 初始化为空指针。t
double
t[0]
double
t[1]
重要的部分是两者之间的区别
double (*t)[2];`
和
double *t[2];
使用顺时针/螺旋规则,第一个定义为“指向两个数组的指针”。第二个定义为“指向 ” 的两个指针的数组。t
double
t
double
我预计这将分配 64 个字节(两个双精度大小的 4 倍)
这是您的期望是正确的。但这是你的结论
也就是说,我预计 t[0] 和 t[1] 各有 4 个双打的空间。为 这个原因,
是错误的。
这条线
double (*t)[2] = malloc(sizeof(*t)*4);
相当于
double (*t)[2] = malloc( sizeof( double[4][2] ) );
因为表达式的类型是 。*t
double[2]
所以并具有数组类型。 等于 。t[0]
t[1]
double[2]
sizeof( double[2] )
16
这是一个演示程序。
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
double( *t )[2] = malloc( sizeof( double[4][2] ) );
printf( "sizeof( double[2] ) = %zu\n", sizeof( *t ) );
printf( "Address of t[0]: %p\n", ( void * )t[0] );
printf( "Address of t[1]: %p\n", ( void * )t[1] );
printf( "(char * )t[0] + sizeof( double[2] ) = %p\n",
( void * )( ( char * )t[0] + sizeof( double[2] ) ) );
}
程序输出可能如下所示
sizeof( double[2] ) = 16
Address of t[0]: 00B971D8
Address of t[1]: 00B971E8
(char * )t[0] + sizeof( double[2] ) = 00B971E8
double (*t)[2] = malloc( sizeof *t * 4 );
创建为 的 4x2 数组,而不是 2x4 数组。结果如下所示:t
double
+---+ +---+
t: | | -----> | | t[0][0]
+---+ + - +
| | t[0][1]
+---+
| | t[1][0]
+ - +
| | t[1][1]
+---+
| | t[2][0]
+ - +
| | t[2][1]
+---+
| | t[3][0]
+ - +
| | t[3][1]
+---+
因此,为什么 和 的地址相距 16 (2 *) 字节。t[0]
t[1]
sizeof (double)
如果要动态分配 的 2x4 数组,则需要将double
double (*t)[4] = malloc( sizeof *t * 2 );
低
T (*p)[COLUMNS] = malloc( sizeof *p * ROWS );
您正在为 的实例分配足够的空间。ROWS
T [COLUMNS]
评论
t[n]
t[0]
t[1]
double
t[0][0], t[0][1], t[1][0], t[1][1], t[2][0], t[2][1], t[3][0], t[3][1]
double t[4][2]
double t[2][4]
2
4
double (*t)[2]
double [2]
t[0]
double [2]
double (*t)[2] = malloc( sizeof(double[4][2]) );
t
double [4][2]