[英]Correct way to access to 2D Array - C
让我们想象一下我有这个动态分配的二维数组:
//Example of a 3 row * 2 columns int array
int (*arr)[2] = malloc(sizeof(int[3][2]));
但是,后来我发现如果我这样做:
arr[0][5] = 1;
编译器没有抱怨,至少用 valgrind 测试,它也没有抱怨。 除非我尝试访问超过分配空间大小的空间,否则不会。
我发现自动数组也会发生同样的情况:
int arr[3][2];
arr[0][5] = 1; //Code works without errors
我现在的问题是:例如声明有什么意义: int arr[3][2];
如果编译器会接受arr[0][5] = 1;
反正?
我正在使用 GCC 编译器
一般来说,不要超过你分配的内存边界。
默认情况下,Clang 会警告这两个示例,而 GCC 会在没有实际使用变量的情况下警告这两个示例(这是死代码消除器的错误)。 如果使用变量或声明为volatile
您可以使用-O2 -Wall -Wextra
启用警告。
使用 GCC 和 Clang 这样做是“安全的”; 每次都会发生同样的事情。
然而,这是未定义的行为,所以这是一个坏主意。 对于执行此操作以使您的计算机长腿并走开的程序来说,这是完全有效的。
进行分配的等效方法是:
arr[2][1] = 1;
这是基于数组元素按顺序存储在内存中的假设。
因此, &arr[5][0]
在技术上与&arr[2][1]
,但不应使用它。
我的建议:
int arr[3][2];
int x, y;
for( x = 0; x < 3; x++ )
for( y = 0; y < 2; y++ )
arr[x][y] = x * y;
这保证是安全的。
在我的电脑 Gcc 8.1.0
#include <stdio.h>
#include <stdlib.h>
int main(){
int i,j;
int (*arr)[2] = malloc(sizeof(int[3][2]));
printf("%p %d %d\n",arr,sizeof(int),sizeof(int[3][2]));
//in my computer print
//00C63E38 4 24
//legal memory from 00C63E38~00C63E4C
for(i=0;i<3;i++){
for(j=0;j<2;j++){
printf("%p ",&arr[i][j]);
}
printf("\n");
}
//00C63E38 00C63E3C
//00C63E40 00C63E44
//00C63E48 00C63E4C
printf("------------------\n");
for(i=0;i<3;i++){
for(j=0;j<2;j++){
printf("%p ",*(arr+i)+j);
}
printf("\n");
}
//00C63E38 00C63E3C
//00C63E40 00C63E44
//00C63E48 00C63E4C
//So arr[i][j] is equel *(arr+i)+j
printf("-------------\n");
for(i=0;i<6;i++){
printf("%p ",arr+i);
printf("\n");
}
printf("-------------\n");
//jump 4*2 pointer address per loop from 00C63E38
//00C63E38
//00C63E40
//00C63E48
//00C63E50
//00C63E58
//00C63E60
for(i=0;i<6;i++){
printf("%p ",arr[0]+i);
printf("\n");
}
//jump 4 pointer address per loop from 00C63E38
//00C63E38
//00C63E3C
//00C63E40
//00C63E44
//00C63E48
//00C63E4C
free(arr);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.