【发布时间】:2021-04-10 12:16:35
【问题描述】:
我一直在编写在许多循环中分配数据的代码,发现使用realloc() 非常方便,因为它一致地处理初始和循环中间数据,而无需添加释放和分配新指针的条件。
我写了这个小测试程序:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
char *x = NULL;
x = realloc (x, 0);
printf ("Address of realloc (NULL, 0): %p\n", x);
assert (x != NULL);
printf ("Address of realloc (x, 8): %p\n", x);
x = realloc (x, 8);
assert (x != NULL);
x = realloc (x, 0);
assert (x == NULL);
printf ("Address of realloc (x, 0): %p\n", x);
x = realloc (x, 21);
printf ("Address of realloc (x, 21): %p\n", x);
assert (x != NULL);
x = realloc (x, 0); // free.
assert (x == NULL);
printf ("Address of realloc (x, 0): %p\n", x);
return 0;
}
并进行内存检查:
$ gcc -Wall -g test_realloc.c -o test_realloc.o
$ valgrind ./test_realloc.o
==1192613== Memcheck, a memory error detector
==1192613== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1192613== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==1192613== Command: ./test_realloc.o
==1192613==
Address of realloc (NULL, 0): 0x4a3a040
Address of realloc (x, 8): 0x4a3a040
Address of realloc (x, 0): (nil)
Address of realloc (x, 21): 0x4a3a510
Address of realloc (x, 0): (nil)
==1192613==
==1192613== HEAP SUMMARY:
==1192613== in use at exit: 0 bytes in 0 blocks
==1192613== total heap usage: 4 allocs, 4 frees, 1,053 bytes allocated
==1192613==
==1192613== All heap blocks were freed -- no leaks are possible
==1192613==
==1192613== For lists of detected and suppressed errors, rerun with: -s
==1192613== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
到目前为止,很好。唯一需要注意的是,初始值必须初始化(甚至是NULL)。
现在我想知道跨平台的可移植性如何。 Linux x86_64 上的 man 3 realloc 非常明确地说明了这种行为,但 realloc (NULL, 0) 在这种情况下会意外产生非 NULL 地址。
我可以在多大程度上依赖这种行为?
编辑:确切地说,我的问题是我是否可以依靠我的示例程序来避免任何平台上的 UB 或内存泄漏。
谢谢。
【问题讨论】:
-
您可以依赖 realloc 的行为,但您需要停止假设它永远不会返回 NULL。
assert不是错误检查。 -
注意
recalloc(ptr,0)调用释放内存不在 C 标准中。 -
@12431234123412341234123 来自手册页:“如果 size 等于 0,并且 ptr 不为 NULL,则调用相当于 free(ptr)。”我应该不依赖手册页吗?便携性?
-
我主要担心我的示例程序在任何平台上都不会出现内存泄漏或 UB。
realloc (NULL, 0)是否产生 NULL 无关紧要,只要我不依赖它。 -
我必须纠正自己:释放大小为 0 的行为是 C89 明确要求的,但在较新的 C 标准中没有。据我了解较新的标准和 POSIX 标准,它甚至不符合释放指针的标准。 TLDR:不要使用
realloc(somePointer,0);。
标签: c memory-management malloc