c - free() 是否适用于重新分配的指针?
问题描述
假设我有以下代码:
int *ptr = (int*) malloc(0), *ptr2;
ptr2 = (int*) malloc(4 * sizeof(int));
*(ptr2 + 1) = 3;
ptr = ptr2;
free(ptr)
调用 free(ptr) 是否适用于新的内存块 ptr 指向或在空指针上?
解决方案
是的,在您的示例ptr
中设置为ptr2
来自malloc
.
所以,free(ptr);
是有效的(例如,就像我们做的那样free(ptr2);
)。
但是,现在,我们已经丢失了 的原始值,ptr
所以第一个块现在 malloc
是内存泄漏。也就是说,没有变量具有原始值,因此它永远不能被释放。
要解决这个问题,但保留您的原始代码,我们可以这样做:
int *ptr = (int *) malloc(0), *ptr2;
ptr2 = (int *) malloc(4 * sizeof(int));
*(ptr2 + 1) = 3;
// to prevent a leak of the first malloc ...
int *ptr3 = ptr;
// without ptr3, this would "leak" the original value of ptr
ptr = ptr2;
free(ptr)
// free the first block ...
free(ptr3);
旁注: malloc
returnsvoid *
适用于任何指针类型,因此无需转换返回值。请参阅:我是否强制转换 malloc 的结果?
所以,在代码中做(例如):
ptr2 = malloc(4 * sizeof(int));
仍然有一些额外的代码复制。如果sizeof(int)
我们改变了ptr2
.
因此,为了“面向未来”的代码,许多人更喜欢:
ptr2 = malloc(sizeof(*ptr2) * 4);
更新:
您还可以添加关于
malloc(0)
具有实现定义的行为的注释。– chqrlie
是的,malloc(0)
具有实现定义的行为。一些可能性:
- 退货
NULL
。海事组织,最佳选择 - 将内部分配视为
malloc(1)
- 返回一个特殊的“零长度”分配。
由于这些原因,我会避免使用。malloc(0)
它是“脆弱的”并且具有边际效用。
我 [大部分] 看到新手程序员使用它,他们计划realloc
在循环中使用并相信他们不能调用realloc
指针NULL
。
但是,realloc
会接受一个NULL
指针就好了。
例如,如果我们要将一个填充了整数的文件读入一个数组,而我们不知道文件中有多少个数字,我们可能会这样做:
#include <stdio.h>
#include <stdlib.h>
int
main(int argc,char **argv)
{
if (argc < 2)
exit(3);
// NOTE: novices do this ...
#if 0
int *ptr = malloc(0);
// NOTE: experienced programmers do this ...
#else
int *ptr = NULL;
#endif
// number of elements in the array
size_t count = 0;
// open the input file
FILE *input = fopen(argv[1],"r");
if (input == NULL) {
perror(argv[1]);
exit(4);
}
while (1) {
// increase array size
ptr = realloc(ptr,sizeof(*ptr) * (count + 1));
// out of memory ...
if (ptr == NULL) {
perror("realloc");
exit(5);
}
// decode one number from file
if (fscanf(input,"%d",&ptr[count]) != 1)
break;
// advance the count
++count;
}
// close the input stream
fclose(input);
// trim array to actual size used
ptr = realloc(ptr,sizeof(*ptr) * count);
// print the array
for (size_t idx = 0; idx < count; ++idx)
printf("%zu: %d\n",idx,ptr[idx]);
// free the array
free(ptr);
return 0;
}
注意:在某些特殊情况下,这样做malloc(0)
确实有意义。通常,必须将指针传递给一些代码,这些代码将区分NULL
与malloc(0)
常规分配。但是,它们是一种高级用法,我不建议初学者使用它们。
推荐阅读
- python-3.x - 当需要 getter 和 setter 方法时如何在 Python 模块之间共享变量
- snowflake-cloud-data-platform - 有没有办法使用任务或存储过程自动将雪花中的数据卸载到本地机器?
- r - cmdscale(dist, k = k) 中的错误:在 phyloseq 中执行 plot_heatmap 时,“d”中不允许存在 NA 值
- php - 使用 Docker WSL2 cUrl 错误窗口创建新的 Laravel 项目
- jwt - 生成 JWT 密钥对
- python - 如何使用python检查youtube视频是否存在?
- if-statement - IF 语句重构的理论?
- python - 如何在 Python 中读取 blob 数据
- amazon-web-services - 如何在不手动检查的情况下使用 AWS 状态仪表板进行更新?
- angular - 类型 TranslateModule 没有 'ɵmod' 属性