[英]Question about pointer to array used in malloc/free
I saw the following code:我看到了以下代码:
#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;
}
This lines makes me very uncomfortable:这条线让我很不舒服:
free(vals);
vals
is a pointer pointing to an array. vals
是指向数组的指针。 This looks right, but I just have a difficult time internalizing it, I do not know why.这看起来不错,但我就是很难将其内化,我不知道为什么。
I am more used to the following style:我比较习惯下面的风格:
int *p = (int*)malloc(n * sizeof(int));
......
free(p);
In this code, p
is a pointer pointing to the start of a memory region for some integers, the malloc and free are symmetric in that they both work on a pointer type;在这段代码中,
p
是一个指针,指向一些整数的 memory 区域的开始,malloc 和 free 是对称的,因为它们都在指针类型上工作; yet the original code has malloc()
working on a pointer to an array and free()
a pointer.然而原始代码有
malloc()
处理指向数组的指针,而free()
处理指针。
Out of curiosity, I modified the original code:出于好奇,我修改了原来的代码:
free(vals); ==> free(*vals);
I was expecting this change will fail at compiler, the reason is *vals
is an array now.我原以为这个更改会在编译器中失败,原因是
*vals
现在是一个数组。 But gcc is fine and valgrind does not complain memory leak.但是 gcc 很好,valgrind 不会抱怨 memory 泄漏。
I know C has a thing called array degenerates to pointer at function call.我知道 C 在 function 调用中有一个叫做数组退化为指针的东西。 But I just cannot internalize this stuff.
但我就是无法将这些东西内化。 Sorry writing so long to describe a problem, wish you could see my struggle.
抱歉写了这么长的时间来描述一个问题,希望你能看到我的挣扎。 Is there a definitive doc/stackoverflow/blog to clear this up - best C99 or later?
是否有明确的文档/stackoverflow/blog 来解决这个问题——最好是 C99 或更高版本?
Thanks!谢谢!
writing free(*vals);
free(*vals);
is same as writing free(vals);
与写
free(vals);
edited your code to clear that a little bit编辑您的代码以清除一点
#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;
}
and this is the output:这是 output:
*val is 0000018190365d50
val is 0000018190365d50
&val is 0000005d9dbff7b8
note that vals
is Array pointer which means that its base type is an array of n integers where the pointer val
is created in that stack and points to the whole array, not the first element only and that array is created in the heap
, to illustrate, look at the following graph:请注意,
vals
是数组指针,这意味着它的基本类型是n 个整数的数组,其中指针val
在该堆栈中创建并指向整个数组,而不仅仅是第一个元素,并且该数组是在heap
创建的,以说明,请看下图:
so for example if you write:所以例如,如果你写:
printf("val is %p\n", vals);
printf("val+1 is %p\n", vals+1);
the output will be: output 将是:
val is 00000207ef0c5d50
val+1 is 00000207ef0c5d78
note the difference between the 2 is about 40 bytes as val
points to the whole array not only one element as in case of int *p = (int*)malloc(n * sizeof(int));
请注意,两者之间的差异约为40个字节,因为
val
指向整个数组,而不仅仅是一个元素,如int *p = (int*)malloc(n * sizeof(int));
note that when I say it points to the whole array, I also mean it points to the base address of the array.请注意,当我说它指向整个数组时,我的意思也是它指向数组的基址。
in case of *Vals
, look at the next graph:在
*Vals
的情况下,请看下一张图:
*Vals
is just an address of the first element of the array which is by the way is same as the base address of the array. *Vals
只是数组第一个元素的地址,顺便说一下,它与数组的基地址相同。
refer to free() manual , they said:参考free() manual ,他们说:
The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc().
free() function 释放 ptr 指向的 memory 空间,该空间必须由先前调用 malloc()、calloc() 或 realloc() 返回。 Otherwise, or if free(ptr) has already been called before, undefined behavior occurs.
否则,或者如果之前已经调用过 free(ptr),则会发生未定义的行为。 If ptr is NULL, no operation is performed.
如果 ptr 为 NULL,则不执行任何操作。
and what does malloc()
function return? malloc()
function 返回什么?
it returns the base address of your reserved space in heap, so writing free(vals);
它返回堆中保留空间的基址,因此写成
free(vals);
is same as writing free(vals);
与写
free(vals);
This codes uses dynamic VLA .此代码使用动态 VLA 。 I think that it may be easier to understand if the code is reformulated with a
typedef
.我认为如果代码用
typedef
重新表述可能更容易理解。
void foo(char n)
{
typedef int T[n];
T *vals = malloc(sizeof(T));
...
free(vals);
}
Now it looks like a tivial use of a single dynamic object.现在它看起来像是对单个动态 object 的简单使用。
To access elements of an array first the pointer has to be dereferenced *vals
forming an array, which decays to int*
pointer suitable for []
operator.要首先访问数组的元素,必须取消引用指针
*vals
形成一个数组,该数组衰减为适合[]
运算符的int*
指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.