提问人:Maciek 提问时间:9/28/2023 更新时间:9/29/2023 访问量:127
“释放”malloc“返回的指针是否总是安全的?
Is it always safe to `free` a pointer returned by `malloc`?
问:
我的理解是,只有当已知两个函数在同一堆上运行时,才允许使用调用返回的指针(或任何其他函数返回指向堆上动态分配的某个内存的指针,如或)进行调用。因此,我理解“一般方法”应该是提供一个互补的释放例程,而不是调用我们从分配它的函数返回的任何指针,因为在一般情况下,我们永远不知道指针是否已经通过任何可以影响它的边界。我认为直接调用我们被提交的指针应该更像是一种特例,当我们确定我们持有的指针对我们来说是安全的(例如,我们 -ed 或它自己,或者我们知道分配它的例程在某个地方“接近”并且指针没有通过任何边界)。free
malloc
strdup
asprintf
free
free
free
strdup
malloced
然而,我已经很久没有做过任何专业的 C 了,当我做过的时候,它并不多,所以我只能知道错了。我遇到了许多观点,即调用任何(有效的、未释放的)恶意指针通常是安全的,并且只有在明确知道有必要时才应使用自定义释放例程。但这在某种程度上与我在 Windows 上使用 Visual Studio 6 的记忆形成了鲜明的对比,在 Windows 上,调用任意已知的恶意指针的成功取决于在“静态/动态链接的运行时”、“调试/发布版本”和“单线程/多线程运行时”的三维兼容性矩阵中分配和解除分配方的位置。free
free
那么我的问题是:调用指针的一般和实用规则是什么,我肯定知道已经是 -ed,而不是 -d?什么时候是安全的,更重要的是,什么时候不安全?如果我创建一个返回 -ed 指针的函数,我是否应该始终提供一个单独的函数来释放它,或者(在一般情况下)是否足以说“通过在我刚刚返回给你的指针上调用 free
来释放返回的内存”?从实际的角度来看,遇到调用不兼容堆并对其进行操作,或者以任何其他方式不对称的情况的可能性有多大?让我们假设指针指向一些微不足道的数据,而不是一些不透明的结构,该结构包含一些额外的簿记信息,并且需要一些复杂的逻辑来释放使用的内存。free
malloc
free
malloc
malloc
free
答:
遇到调用 malloc 并自由操作的情况 不兼容的堆,或者以任何其他方式不对称?让我们 假设指针指向一些微不足道的数据,而不是 到一些不透明的结构,其中包含一些额外的簿记 信息,并且需要一些复杂的逻辑来释放使用的 记忆。
该语言对堆一无所知。它只知道对象的存储持续时间。由族函数创建的对象已分配存储持续时间。分配的存储持续时间对象一直存在,直到通过调用函数释放该对象。因此,符合要求的程序应该对任何内存安全C
malloc
free
free
malloc
如果您的程序不符合要求,并且使用了许多不同的实现(即动态库使用与主程序不同的实现),那么很明显,您的主程序不应该用于由 的不同实现 分配的对象。malloc
free
malloc
...调用的一般和实用规则是什么......?
什么时候是安全的,更重要的是,什么时候不安全?free
free(NULL)
总是好的。
否则:
在来自的任何指针上调用一次 ,都是可以且定义良好的。
free()
malloc(), calloc(), realloc(), strdup(), aligned_alloc()
释放指针后,不要再次释放它。
不要尝试取消引用自由指针。
使用这些函数,不存在不兼容的堆问题。
不要调用源自其他地方的其他指针。
free()
评论
请注意,这是在 Linux 上。我不知道 VSC 是否/如何不同。Library Functions Manual
The free() function frees the memory space pointed to by ptr, which must have
been returned by a previous call to malloc() or related functions. Otherwise,
or if ptr has already been freed, undefined behavior occurs. If ptr is NULL,
no operation is performed.
TLDR 是的,只要您每个指针的执行次数不超过一次。
评论
malloc()
free()
mmap()
malloc()
free()
free()
NULL
free()