【问题标题】:calloc problem - malloc.c:2385 error - how does calloc/malloc work?calloc 问题 - malloc.c:2385 错误 - calloc/malloc 是如何工作的?
【发布时间】:2021-05-20 11:43:16
【问题描述】:

运行我的程序时,我收到以下错误:

malloc.c:2385: sysmalloc: 断言`(old_top == initial_top (av) && 旧尺寸 == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' 失败。

完整的代码很大,但我设法在复制中找到了一些有趣的东西,我不明白为什么会这样。非常感谢任何帮助和/或解释。

这是没有失败时的代码的 sn-p:

static void adjacent_list_get(struct elem **elem_list,
                          struct elem *element,
                          uint32_t *size) {

struct elem **t_elem_list;

t_elem_list = calloc((size_t) 1, sizeof(*t_elem_list));     

if (!elem_list) {       
...

这是失败时的代码的sn-p:

static void adjacent_list_get(struct elem **elem_list,
                          struct elem *element,
                          uint32_t *size) {

struct elem **t_elem_list;

if (!elem_list) {   
        t_elem_list = calloc((size_t) 1, sizeof(*t_elem_list)); 
        ...

在执行过程中,elem_listNULL,所以if 语句为真,它进入了那个块;但随后它因上述错误而失败。

我无法理解同一行,同一 calloc 如何在同一函数中失败,具体取决于它是在 if 块内部还是外部。我在这里遗漏了一些东西,我在互联网上找不到任何解释。

【问题讨论】:

  • 您可能正在破坏一些由内存管理器用于记账的堆内存,这很可能是由于缓冲区溢出。仅通过查看您提供的代码的 sn-ps 就很难跟踪。我建议使用 ASAN 重建您的程序,这可能会在损坏发生时检测到。
  • 通过 valgrind 运行您的代码。如果你对内存管理不善,它会告诉你在哪里。
  • 好的,如果我理解正确,这只是其他地方问题的征兆?
  • 不一定,但很有可能。
  • 好的,这是一个典型的未定义行为错误。您在某处有可疑的代码,可能会导致堆损坏。无法复制。

标签: c malloc calloc


【解决方案1】:

calloc/malloc 是如何工作的?

这在很大程度上取决于您的实现。

calloc/malloc 的一些实现是开源的:尝试在笔记本电脑上安装Debian,研究GNU libcmusl-libc 的源代码,并阅读Linux From Scratch。然后malloc有时使用像mmap(2)sbrk(2) 这样的系统调用。大多数时候malloc 会重用以前的freed 内存区域。

另请参阅 this answer 以了解 malloc 的玩笑实现,我认为它符合某些 C 标准(例如 n1570 或更好)。

另一方面,在 Windows 中阅读malloc 的源代码是为少数快乐的人保留的。

在像Arduino 这样的微控制器上,malloc 的工作方式非常不同。

【讨论】:

  • 也许从字面上回答了标题中的问题,但这实际上不是 OP 的问题。很可能它们正在破坏内存。
  • 在 Windows 中阅读 malloc 的源代码仅限于少数快乐的人。 不... ma-no.org/en/software/operating-systems/…
  • @DavidRanieri 阅读 Windows 的整个源代码以寻找堆例程听起来并不像把我放在一个叫做“快乐少数”的类别中。我在阅读 Linux 内核时做了类似的事情,从 Linux 粉丝变成了与所有 Linux 计算机保持 10 米安全距离的人。一点都没有让我开心。
  • @Lundin findgrep 是你的朋友,是的,将源代码放在 linux 设备中,或者如果你愿意,可以在 windows 上安装和使用这些实用程序(我不记得包的名称,但它工作正常)
  • @DavidRanieri 我只是说阅读这种高度专业化的庞大代码库,它已经通过强制“代码腐烂”进行了大约 30 年的维护,并不是我要达到的目标一个快乐的地方:)
猜你喜欢
  • 2021-02-02
  • 2012-03-02
  • 2018-05-28
  • 2017-05-06
  • 2010-12-05
  • 2011-01-13
  • 1970-01-01
  • 2013-11-17
相关资源
最近更新 更多