use*_*174 -5 c pointers declaration pointer-to-pointer
int **arr = (int **)malloc(r * sizeof(int *));
Run Code Online (Sandbox Code Playgroud)
我该如何解释上述C代码的含义?
致电malloc():
int **arr = (int **)malloc(r * sizeof(int *));
Run Code Online (Sandbox Code Playgroud)
为r指针分配空间int,并返回void *指向分配的指针.然后将此指针强制转换为int **并分配给arr指针,指针指向该指针int.因此arr指向分配区域的第一个元素,它是指向的指针int.这样的代码可以用于创建"锯齿状"数组,其中数组的每一行是分开分配的; 这意味着分配在内存中可能不是连续的,因此这不是真正的2d数组.请参阅正确分配多维数组以阅读有关此内容的更多信息.
不过,以上被认为是不好的风格.最重要的是,sizeof应尽可能避免使用显式类型作为运算符的参数:
int **arr = (int **)malloc(r * sizeof *arr);
Run Code Online (Sandbox Code Playgroud)
如果arr在代码的生命周期中的某些点发生更改的类型,这不易出错,并且更易于维护.
此外,不需要malloc()在C中转换结果,因此这个转换是多余的,只会使代码混乱:
int **arr = malloc(r * sizeof *arr);
Run Code Online (Sandbox Code Playgroud)
作为最后的改进,我更喜欢sizeof在这种情况下首先放置表达式:
int **arr = malloc(sizeof *arr * r);
Run Code Online (Sandbox Code Playgroud)
这在上面的特定情况下是无用的改变,但是当存在额外的乘法时,例如:
int **arr = malloc(sizeof *arr * r * n);
Run Code Online (Sandbox Code Playgroud)
这保证了算法的执行类型至少与宽度一样size_t,降低了整数溢出的风险(signed整数溢出导致C中的未定义行为),并且可以降低unsigned整数环绕的风险(明确定义,但可能意外或不受欢迎).