为什么同时使用 malloc/calloc/realloc 和 brk 函数会导致未定义的行为?

Why using both malloc/calloc/realloc and brk functions will results in undefined behavior?

提问人:chroshimmer 提问时间:2/22/2023 更新时间:2/22/2023 访问量:120

问:

这是否意味着同时使用(malloc 或 calloc 或 realloc)之一和 (brk/sbrk) 之一会导致 UB,或者同时使用 malloc 和 calloc 也会导致 UB?

这是通过整个程序发生的,还是只是一个源文件?

c malloc 动态内存分配 calloc brk

评论

1赞 user253751 2/22/2023
你在哪里看到的?
0赞 Tom Karzes 2/22/2023
我认为一般的建议是避免使用 和 .函数系列使用它们,通常应该足以满足内存分配需求。brksbrkmalloc
0赞 chroshimmer 2/22/2023
这是我今天学习的机器组织课
0赞 Support Ukraine 2/22/2023
"...同时使用 malloc 和 calloc 也会导致 UB?同一程序中没有 malloc 和 calloc 是可以的。没关系。只有当您也使用 brk/sbrk 时才有问题
0赞 Richard Chambers 2/25/2023
这回答了你的问题吗?sbrk() 如何在 C++ 中工作?

答:

3赞 zwol 2/22/2023 #1

在同时具有 和 的系统上,实际规则是“的实现可以假设除了自身之外没有其他代码调用非零参数。sbrkmallocmallocsbrk

这样说,后果就容易推断出来了:

  • 每个进程只能有一个操作实现。(在这样的系统上,操作系统提供的 C 库通常被设计为在提供另一个实现时注意到并优雅地退出。mallocmalloc

  • 可以随心所欲地打电话。sbrk(0)

  • 如果你正在编写一个实现 ,你可以直接用一个非零参数来调用,并假设没有其他人会这样做。mallocsbrk

  • 但是,如果您编写 的实现,则使用非零参数进行调用可能会导致下一次调用(或内部调用的任何函数,可以是其中任何一个函数,但记录为异步信号安全的函数除外)使进程崩溃或损坏堆。mallocsbrkmallocmalloc

    应该很容易理解为什么从实现外部使用否定参数进行调用会产生这种效果。你缩小了堆!您拿走的空间中可能有分配!几乎可以肯定那里有内部簿记结构!sbrkmallocmalloc

    为什么用一个积极的论点来打电话可以产生同样的效果,这是更微妙的。 不会知道额外的空间。下次调用自身时,它将错误地更新其内部簿记结构。堆中间将有一大块内存无法跟踪。它很可能会在该内存上乱涂乱画和/或混淆自己访问堆外部的地址。sbrkmallocmallocsbrk

评论

0赞 Richard Chambers 2/25/2023
另请参阅这篇文章,sbrk()如何在C++中工作?它有一些不错的答案。