c# 为什么错位的2D数组的地址不是我所期望的?

inkz8wg9  于 2023-02-14  发布在  C#
关注(0)|答案(2)|浏览(171)

为了在C I运行中为2D数组分配内存

double (*t)[2] = malloc(sizeof(*t)*4);

我期望分配64字节(两个double的4倍),也就是说,我期望t[0]和t[1]各有4个double的空间,因此,我认为t[0]和t[1]的地址应该分隔32字节,但是,我发现它们分隔了16字节(对应于只有两个double)。

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

我错过了什么?

c8ib6hqw

c8ib6hqw1#

这里的声明和分配好像有点误会,你声明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];

使用the clockwise/spiral rule,第一个定义t为“指向两个double的数组的指针“,第二个定义t为“指向double的两个指针的数组“。

z5btuh9x

z5btuh9x2#

我期望这个分配64字节(两个双精度数大小的4倍)
你的期望是正确的,但这是你的结论
也就是说,我期望t [0]和t [1]各有4个double的空间。因此,
是错的。
这条线

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

相关问题