[英]Question about pointer to array used in malloc/free
我看到了以下代码:
#include <stdlib.h>
void foo(char n)
{
int (*vals)[n] = malloc(sizeof(int[n]));
for (int i = 0; i < n; ++i)
(*vals)[i] = i;
free(vals);
}
int main(int argc, char **argv)
{
foo(*(argv[1]));
return 0;
}
这条线让我很不舒服:
free(vals);
vals
是指向数组的指针。 这看起来不错,但我就是很难将其内化,我不知道为什么。
我比较习惯下面的风格:
int *p = (int*)malloc(n * sizeof(int));
......
free(p);
在这段代码中, p
是一个指针,指向一些整数的 memory 区域的开始,malloc 和 free 是对称的,因为它们都在指针类型上工作; 然而原始代码有malloc()
处理指向数组的指针,而free()
处理指针。
出于好奇,我修改了原来的代码:
free(vals); ==> free(*vals);
我原以为这个更改会在编译器中失败,原因是*vals
现在是一个数组。 但是 gcc 很好,valgrind 不会抱怨 memory 泄漏。
我知道 C 在 function 调用中有一个叫做数组退化为指针的东西。 但我就是无法将这些东西内化。 抱歉写了这么长的时间来描述一个问题,希望你能看到我的挣扎。 是否有明确的文档/stackoverflow/blog 来解决这个问题——最好是 C99 或更高版本?
谢谢!
free(*vals);
与写free(vals);
编辑您的代码以清除一点
#include <stdlib.h>
#include <stdio.h>
void foo(char n)
{
int (*vals)[n] = malloc(sizeof(int[n]));
for (int i = 0; i < n; ++i)
(*vals)[i] = i;
printf("*val is %p\n", *vals);
printf("val is %p\n", vals);
printf("&val is %p\n", &vals);
free(vals);
}
int main()
{
foo(10);
return 0;
}
这是 output:
*val is 0000018190365d50
val is 0000018190365d50
&val is 0000005d9dbff7b8
请注意, vals
是数组指针,这意味着它的基本类型是n 个整数的数组,其中指针val
在该堆栈中创建并指向整个数组,而不仅仅是第一个元素,并且该数组是在heap
创建的,以说明,请看下图:
所以例如,如果你写:
printf("val is %p\n", vals);
printf("val+1 is %p\n", vals+1);
output 将是:
val is 00000207ef0c5d50
val+1 is 00000207ef0c5d78
请注意,两者之间的差异约为40个字节,因为val
指向整个数组,而不仅仅是一个元素,如int *p = (int*)malloc(n * sizeof(int));
请注意,当我说它指向整个数组时,我的意思也是它指向数组的基址。
在*Vals
的情况下,请看下一张图:
*Vals
只是数组第一个元素的地址,顺便说一下,它与数组的基地址相同。
参考free() manual ,他们说:
free() function 释放 ptr 指向的 memory 空间,该空间必须由先前调用 malloc()、calloc() 或 realloc() 返回。 否则,或者如果之前已经调用过 free(ptr),则会发生未定义的行为。 如果 ptr 为 NULL,则不执行任何操作。
malloc()
function 返回什么?
它返回堆中保留空间的基址,因此写成free(vals);
与写free(vals);
此代码使用动态 VLA 。 我认为如果代码用typedef
重新表述可能更容易理解。
void foo(char n)
{
typedef int T[n];
T *vals = malloc(sizeof(T));
...
free(vals);
}
现在它看起来像是对单个动态 object 的简单使用。
要首先访问数组的元素,必须取消引用指针*vals
形成一个数组,该数组衰减为适合[]
运算符的int*
指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.