在指向动态声明的数组元素的指针上调用 free
Calling free on a pointer to an element of an array declared dynamically
当我运行以下代码时:
int main(int* argc, char** argv) {
int* array = malloc(5 * sizeof(int));
free(array + 3);
}
我收到错误 pointer being freed was not allocated
。我的直觉是,free
并没有试图释放 array
的第四个元素,而是试图释放在其最后一个元素之后 3*sizeof(int)
字节的东西。这个对吗?如果是这样,那么为什么会发生这种情况?执行该程序所产生的行为是否总是可预测的,或者它是否未定义特定于实现?
malloc
分配一块内存。
您只能取消分配 (free
) 此块。您不能释放单个元素或块的一部分。
您可以重新分配(realloc
)此块以使其变大或变小。
来自 free()
的规范:
Synopsis
#include <stdlib.h>
void free(void*ptr);
Description
The free
function causes the space pointed to by ptr
to be deallocated, that is, made available for further allocation. If ptr
is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free
or realloc
, the behavior is undefined.
因此,您试图做的是未定义的行为
free
希望您使用从 malloc
返回的完全相同的地址,否则可能会发生任何事情。 malloc
调用为每个调用分配一个完整的段,在本例中为 5 int
大。释放这个段的一部分没有意义,堆不是这样工作的。
堆首先分配一个段header,这是包含大小等的内部信息。然后header,所有数据。此 header 部分对程序员不可见,它的实现方式是 OS and/or C 库特定的。
事实上,在您的情况下,您将一个位于 3*sizeof(int)
字节的地址传递到段的数据部分,这不是有效地址,因为 free 需要 malloc
使用的初始地址为了知道该段的内部 header 从哪里开始。当您将错误的地址传递给它时,它可能会获取随机数据的其他部分并将其视为 header。行为未定义。
(但是,您可以将空指针传递给 free()
,这保证是 no-op。)
当我运行以下代码时:
int main(int* argc, char** argv) {
int* array = malloc(5 * sizeof(int));
free(array + 3);
}
我收到错误 pointer being freed was not allocated
。我的直觉是,free
并没有试图释放 array
的第四个元素,而是试图释放在其最后一个元素之后 3*sizeof(int)
字节的东西。这个对吗?如果是这样,那么为什么会发生这种情况?执行该程序所产生的行为是否总是可预测的,或者它是否未定义特定于实现?
malloc
分配一块内存。
您只能取消分配 (free
) 此块。您不能释放单个元素或块的一部分。
您可以重新分配(realloc
)此块以使其变大或变小。
来自 free()
的规范:
Synopsis
#include <stdlib.h> void free(void*ptr);
Description
The
free
function causes the space pointed to byptr
to be deallocated, that is, made available for further allocation. Ifptr
is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call tofree
orrealloc
, the behavior is undefined.
因此,您试图做的是未定义的行为
free
希望您使用从 malloc
返回的完全相同的地址,否则可能会发生任何事情。 malloc
调用为每个调用分配一个完整的段,在本例中为 5 int
大。释放这个段的一部分没有意义,堆不是这样工作的。
堆首先分配一个段header,这是包含大小等的内部信息。然后header,所有数据。此 header 部分对程序员不可见,它的实现方式是 OS and/or C 库特定的。
事实上,在您的情况下,您将一个位于 3*sizeof(int)
字节的地址传递到段的数据部分,这不是有效地址,因为 free 需要 malloc
使用的初始地址为了知道该段的内部 header 从哪里开始。当您将错误的地址传递给它时,它可能会获取随机数据的其他部分并将其视为 header。行为未定义。
(但是,您可以将空指针传递给 free()
,这保证是 no-op。)