我有一个不寻常的情况。 这是片段:
int i, j;
short ** s = (short **)malloc(128);
for(i = 0; i < 14; i++){
s[i] = (short *)malloc(128);
for(j = 0; j < 128; j++)
s[i][j] = 0;
}
printf("Value of s[%d][%d] = %d\n",2,40,s[2][40]);
s[1][108] = 99;
printf("Value of s[%d][%d] = %d\n",2,40,s[2][40]);
我运行时获得的输出是:Value of s[2][40] = 0
Value of s[2][40] = 99
消除循环并写短s [14] [128]产生正确的输出(两个打印中s [2] [40]的值为0)
为什么我能用s [1] [108]访问s [2] [40]? 我在Ubuntu 12.04上使用gcc。
答案 0 :(得分:6)
您正在访问您分配的空间范围,这会导致未定义的行为。
s[i] = (short *)malloc(128)
分配128个字节。但是你试着写128个短裤到那个空间。由于短路大于1个字节,因此您将在分配结束时运行。
此外,short ** s = (short **)malloc(128);
可能会分配太多空间,因为您只使用了14行。
假设你想要一个14 x 128的数组:
short **s = malloc( 14 * sizeof *s );
for (size_t i = 0; i < 14; ++i)
s[i] = malloc( 128 * sizeof *s[i] );
malloc
获取字节数,因此您必须将元素数乘以每个元素的大小。
请注意,如果您不需要能够使不同行具有不同大小的功能,那么您可以在一个块中分配它:
short (*s)[128] = malloc( 14 * sizeof *s );
在这两种情况下,您都可以使用s[i][j]
。
最后,您还应检查malloc
返回的指针是否为NULL
,并且在完成内存后还检查指针free
。
答案 1 :(得分:0)
首先,它不是为2D阵列分配内存的正确方法 -
short ** s = (short **)malloc(128);
for(i = 0; i < 14; i++){
s[i] = (short *)malloc(128);
这是错误的方式!
short ** s = (short **)malloc(128);
这里为short **
分配128字节数组的内存。
for(i = 0; i < 14; i++){
s[i] = (short *)malloc(128);
但您只使用了14 short *
。那只是使用了28个字节(因为sizeof(短)= 2)。
为什么我可以使用s[2][40]
访问s[1][108]
? - 因为您正在访问数组超出范围!
如何?
s[i] = (short *)malloc(128);
这将为每个short *
的128字节数组分配内存。这意味着您可以在每个1D阵列中存储最多64个短元素。
但是您正在尝试访问s[1][108]
- 表示数组第一行中的第108个元素。它超出了分配的内存范围。所以你不会得到预期的输出。
尝试像这样分配内存 -
short **s = malloc(sizeof(short *) * 14);
for(i = 0; i < 14; i++){
s[i] = malloc(sizeof(short) * 128);