我是C语言的新手,所以这个“问题”对我来说非常混乱。
我想使用int指针(行)数组创建2D数组,指向一个内存块中的int(列)数组。我做了它并且它有效,但我不确定为什么我检查了一些东西。
我使用malloc在堆中分配48个字节(2x4数组)(我在x86-64机器上):
int **a;
a = (int **)malloc(sizeof(int*) * 2 + sizeof(int) * 2 * 4);
现在假设这是内存中的整个48个字节。我想要2行的数组,所以我需要2个指向整数数组的指针 - 一个[0],一个[1]:
----------------------------------------------------------------
| a[0] | a[1] | |
----------------------------------------------------------------
^
|
我假设所有指针都是8个字节长,而[2](箭头)的地址是我可以开始存储我的值(int数组)的地方。所以我做了......
int *addr = (int*)&a[2];
a[0] = addr;
addr += 4;
a[1] = addr;
这完全正常,我可以轻松填充和打印2D数组。问题是,当我写int *addr = (int*)&a[2];
时,我确信这将是[0]加2 * 8字节的地址,但事实并非如此。我在另一个例子中用这个简单的代码检查了它:
int *p;
int **k;
p = (int*) malloc(30);
k = (int**) malloc(30);
printf("&p = %p %p %p\n", &p[0], &p[1], &p[2]);
printf("&k = %p %p %p\n", &k[0], &k[1], &k[2]);
输出:
&p = 0x14d8010 0x14d8014 0x14d8018 <-- ok (int = 4 bytes)
&k = 0x14d8040 0x14d8048 0x14d8050 <-- something wrong in my opinion (ptrs = 8 bytes)
我的问题是:为什么数组中指针的第三个地址是 0x14d8050 而不是 0x14d8056 。我想这可能是因为0x14d8056不是最好的地址,但是为什么会这样,为什么它只在处理指针数组时才会发生?我在x86机器上检查了这个并且指针有“正常”值
&p = 0x8322008 0x832200c 0x8322010
&k = 0x8322030 0x8322034 0x8322038
我知道这对某人来说可能是一个明显甚至是愚蠢的问题所以请至少与这些行为的信息分享一些链接。谢谢。
答案 0 :(得分:0)
以0x
为前缀的数字以 hexa 十进制表示。
因此,0x14d8048 + 8 == 0x14d8050
是预期的。
答案 1 :(得分:0)
正如 timrau 在评论中所说的0x14d8048 + 8不是0x14d8056而是0x14d8050,因为它的十六进制
关于你的2D阵列,我不确定它为什么有效,但这不是创建它的方法。
有两种创建2D数组的方法,第一种和简单的是#34;静态&#34;它是这样的:int a[2][4];
。
第二个,你试过的那个是动态的,稍微复杂一点,就像这个
int **a;
int i;
a = malloc(2 * sizeof(*int));
for(i = 0 ; i < 2 ; i++)
a[i] = malloc(4 * sizeof(int));