【问题标题】:realloc crashing in previously stable functionrealloc 在以前稳定的函数中崩溃
【发布时间】:2023-03-05 00:49:01
【问题描述】:

显然,SDL_Mixer 中的这个函数一直在死去,我不知道为什么。有没有人有任何想法?根据 Visual Studio 的说法,崩溃是由 Windows 在 realloc() 行中的某处触发断点引起的。

有问题的代码来自 SDL_Mixer 的 SVN 版本,如果有区别的话。

static void add_music_decoder(const char *decoder) 
{ 
  void *ptr = realloc(music_decoders, num_decoders * sizeof (const char **)); 
  if (ptr == NULL) { 
    return; /* oh well, go on without it. */ 
  } 
  music_decoders = (const char **) ptr; 
  music_decoders[num_decoders++] = decoder; 
} 

我使用的是 Visual Studio 2008,music_decoders 和 num_decoders 都是正确的(music_decoders 包含一个指针,指向字符串“WAVE”和 music_decoders。ptr 是 0x00000000,我能说的最好的情况是,崩溃似乎是在 realloc() 函数中。有人知道我该如何处理这个崩溃问题吗?如果归根结底,我不介意为了完成这项工作而进行一些重构。

【问题讨论】:

  • 您是否在调试模式下构建?如果是这样,您可以在此处获得更多详细信息。它究竟在哪里崩溃?为什么会触发断点? (Windows 通常会告诉你原因)等等。
  • 在调试模式下构建,将生成的 SDL_Mixer.DLL 文件和 *.pdb 文件复制到正在使用它的程序,在调试模式下构建/运行该程序,当它崩溃时,我看到崩溃发生在上述区域。
  • 这是标记为 C++,但 SDL 项目是用 C 编写的。在 C++ 中,您可能会使用 std::vector,以避免出错的机会...

标签: c++ windows visual-studio-2008 breakpoints realloc


【解决方案1】:

一方面,分配num_decoders 指针数组,然后写入该数组中的索引num_decoders 是无效的。大概是第一次调用这个函数时,它分配了 0 个字节并写了一个指向结果的指针。这可能会破坏内存分配器的结构,从而在调用 realloc 时导致崩溃/断点。

顺便说一句,如果您报告错误,请注意add_chunk_decoder(在mixer.c 中)以相同的方式损坏。

我会替换

void *ptr = realloc(music_decoders, num_decoders * sizeof (const char **));

void *ptr = realloc(music_decoders, (num_decoders + 1) * sizeof(*music_decoders)); 

【讨论】:

    【解决方案2】:

    确保 SDL_Mixer.DLL 文件和您的程序构建使用相同的 C 运行时设置。有可能使用一个 CRT 分配内存,并使用另一个 CRT 重新分配内存。

    在项目设置中,查找 C/C++ -> 代码生成。两者的运行时库设置应该相同。

    【讨论】:

      【解决方案3】:

      music_decoders[num_decoders++] = 解码器;

      你是这里的一员。如果 num_decoders 是数组的大小,则最后一个索引是 num_decoders - 1。因此,您应该将该行替换为:

      music_decoders[num_decoders-1] = 解码器;

      您可能希望在函数的开头而不是末尾增加 num_decoders,因为您想重新考虑新的大小,而不是旧的。

      还有一件事:你想将大小乘以 sizeof (const char *),而不是双星。

      【讨论】:

      • "在函数开头增加 num_decoders" - 如果是这样,记得在失败的情况下撤消它。
      【解决方案4】:

      啊,C 编程的乐趣。 realloc(或 malloc 或 free)中的崩溃可以通过写入超出内存块的边界来触发——这可能发生在程序中的其他任何地方。我过去使用的方法有点像debugging malloc 包。在加入第三方解决方案之前,请查看文档以查看 Visual Studio 是否提供了类似这些方面的任何内容。

      【讨论】:

        【解决方案5】:

        崩溃通常不会由断点触发。您是崩溃、由于断点而中断还是在处理断点期间崩溃?

        调试输出窗口应该有一些关于为什么 CRT 断点被命中的信息。例如,它可能会在内存操作期间注意到原始块周围的保护字节已被修改(由于在 add_music_decoder 甚至调用之前发生的缓冲区溢出)。 CRT 将在释放内存时检查这些保护页,并可能在重新分配内存时检查这些保护页。

        【讨论】:

        • 不,输出窗口中什么都没有,而且弹出的错误肯定说这是一个窗口触发的断点。
        猜你喜欢
        • 2018-12-22
        • 2013-08-23
        • 2016-06-25
        • 1970-01-01
        • 1970-01-01
        • 2016-11-29
        • 2015-06-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多