【问题标题】:"Incorrect checksum for freed object" in library's destructors库的析构函数中的“已释放对象的校验和不正确”
【发布时间】:2014-08-19 01:33:29
【问题描述】:

我正在尝试对音频信号的某些部分(读作std::vector<double>)进行一些测量,这涉及使用Aquila 进行的一些信号处理。我正在使用与their example 中相同的函数来计算 MFCC 常数,但不是Aquila::SineGenerator,而是从向量using this constructor 创建一个Aquila::SignalSource

我的功能,删除了不相关的代码,是:

void measure(std::vector<double> &output_vector, std::vector<double> &audio, int start_index, int end_index) {
    // Copy the raw note over.
    std::vector<double> note_audio(end_index - start_index);
    std::copy(audio.begin() + start_index, audio.begin() + end_index, note_audio.begin());

    // Calculate the MFCC constants.
    Aquila::SignalSource input(note_audio, 44100);
    Aquila::Mfcc mfcc(input.getSamplesCount());
    auto mfccValues = mfcc.calculate(input);

    // Copy them over to the output vector.
    for (int i = 0; i < mfccValues.size(); i++) {
        output_vector.push_back(mfccValues[i]);
    }
}

当它运行时 - 通常,但不总是,第二次或第三次调用它 - 它会崩溃并输出:

prog(15384,0x7fff7cafb310) malloc: *** error for object 0x7f8781863208: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

所以,我启动 lldb 并进行调试,在 malloc_error_break 处设置断点,并获取此堆栈跟踪:

(lldb) bt
* thread #1: tid = 0x23c194, 0x00007fff8f487bc0 libsystem_malloc.dylib`malloc_error_break, queue = 'com.apple.main-thread', stop reason = breakpoint 1.2
  * frame #0: 0x00007fff8f487bc0 libsystem_malloc.dylib`malloc_error_break
    frame #1: 0x00007fff8f4815c7 libsystem_malloc.dylib`szone_error + 386
    frame #2: 0x00007fff8f482e1a libsystem_malloc.dylib`small_free_list_remove_ptr + 291
    frame #3: 0x00007fff8f47f737 libsystem_malloc.dylib`szone_free_definite_size + 3429
    frame #4: 0x00000001000029a5 prog-debug`std::__1::__vector_base<double, std::__1::allocator<double> >::~__vector_base() [inlined] std::__1::__deallocate(__ptr=0x00000001008f3800) + 421 at new:164
    frame #5: 0x000000010000299c prog-debug`std::__1::__vector_base<double, std::__1::allocator<double> >::~__vector_base() [inlined] std::__1::allocator<double>::deallocate(this=0x0000000100307888, __p=0x00000001008f3800, (null)=6300) + 8 at memory:1636
    frame #6: 0x0000000100002994 prog-debug`std::__1::__vector_base<double, std::__1::allocator<double> >::~__vector_base() [inlined] std::__1::allocator_traits<std::__1::allocator<double> >::deallocate(__a=0x0000000100307888, __p=0x00000001008f3800, __n=6300) + 24 at memory:1447
    frame #7: 0x000000010000297c prog-debug`std::__1::__vector_base<double, std::__1::allocator<double> >::~__vector_base(this=0x0000000100307878) + 380 at vector:476
    frame #8: 0x0000000100002e25 prog-debug`std::__1::vector<double, std::__1::allocator<double> >::~vector(this=0x0000000100307878) + 21 at vector:481
    frame #9: 0x0000000100002355 prog-debug`std::__1::vector<double, std::__1::allocator<double> >::~vector(this=0x0000000100307878) + 21 at vector:481
    frame #10: 0x000000010004b99c prog-debug`Aquila::MelFilter::~MelFilter() + 28
    frame #11: 0x000000010004b975 prog-debug`Aquila::MelFilter::~MelFilter() + 21
    frame #12: 0x000000010004b8b7 prog-debug`std::__1::__vector_base<Aquila::MelFilter, std::__1::allocator<Aquila::MelFilter> >::~__vector_base() + 279
    frame #13: 0x000000010004b795 prog-debug`std::__1::vector<Aquila::MelFilter, std::__1::allocator<Aquila::MelFilter> >::~vector() + 21
    frame #14: 0x000000010004b775 prog-debug`std::__1::vector<Aquila::MelFilter, std::__1::allocator<Aquila::MelFilter> >::~vector() + 21
    frame #15: 0x000000010004b755 prog-debug`Aquila::MelFilterBank::~MelFilterBank() + 21
    frame #16: 0x000000010004b545 prog-debug`Aquila::MelFilterBank::~MelFilterBank() + 21
    frame #17: 0x000000010004b463 prog-debug`Aquila::Mfcc::calculate(Aquila::SignalSource const&, unsigned long) + 323
    frame #18: 0x00000001000203b6 prog-debug`measure(the_vector=0x00007fff5fbfd8c8, audio=0x00007fff5fbfe478, start_index=7078, end_index=13378) + 1270 at measureVector.cpp:62
    frame #19: 0x0000000100018eb2 prog-debug`extractVectors(vectors=0x00007fff5fbfe4e0, audio=vector<double, std::__1::allocator<double> > at 0x00007fff5fbfe478, sample_rate=44100, bg_audio=vector<double, std::__1::allocator<double> > at 0x00007fff5fbfe460, bg_sample_rate=44100, notes=0x00007fff5fbfe490) + 3234 at extractVectors.cpp:74
    frame #20: 0x000000010002b915 prog-debug`train(results=0x00007fff5fbff620, training_path=std::__1::string at 0x00007fff5fbff608, bg_audio=vector<double, std::__1::allocator<double> > at 0x00007fff5fbff5f0, bg_sample_rate=44100, classes=0x00007fff5fbff638) + 5733 at train.cpp:44
    frame #21: 0x00000001000211d3 prog-debug`MUSE(input_path=std::__1::string at 0x00007fff5fbff948, training_path=std::__1::string at 0x00007fff5fbff930, noise_profile_path=std::__1::string at 0x00007fff5fbff908, output_path=std::__1::string at 0x00007fff5fbff8f0) + 995 at muse.cpp:44
    frame #22: 0x00000001000217fd prog-debug`main(argc=5, argv=0x00007fff5fbffab8) + 717 at muse.cpp:55

有时我会明白,有时我会在内部得到其他错误 (you can see them here),但它们都以 Aquila::Mfcc::calculate() 开头,并且通常似乎涉及析构函数。我遇到了看起来相似的错误,并且是由于尝试返回基于堆栈的变量(哎呀-这就是为什么我要传入我的 output_vector 并在函数中对其进行修改的原因),但是我在这里看不到-我正在使用它,然后将 double 值复制到我的输出向量中。我尝试使用newnote_audio 创建为指针,我尝试在堆栈和堆上将其创建为数组而不是std::vector,但无济于事。

使用 CMake 和 LLVM 在 OS X Mavericks 上构建 C++11。根据 cmets 中的建议,我保存了 the first ~300 lines of a Valgrind output 的要点(尽管它一直持续到 >100 个错误)。我在这里错过了什么?

【问题讨论】:

  • 提示:你可以简单地写std::vector&lt;double&gt; note_audio(audio.begin() + start_index, audio.begin() + end_index);,不需要复制,也不需要所有的默认构造。
  • 您使用的是什么平台、编译器等。 valgrind 在您的系统上可用吗?如果是这样,请运行它以获取有关滥用内存的详细信息。
  • @DaleWilson:菜鸟的错误,对不起!在 OS X Mavericks 上构建 C++11,使用 CMake 和 LLVM,我听说 Valgrind 不适用于 Mavericks (stackoverflow.com/questions/19719762/…),但也许是这样? (calvinx.com/2014/05/04/valgrind-on-mac-os-x-10-9-mavericks)。我会看看我是否可以让它工作并报告。
  • @DaleWilson:我运行了 Valgrind 并得到了很长的输出,看起来有一堆错误(虽然我不确定如何解释它们)。前 300 行左右的内容位于此要点gist.github.com/cnvandev/8c47a1c42527bc7dc32f。我知道Address 0xa4a050 is 0 bytes after a block of size 25,200 alloc'd 通常是指在 25,200 长度向量上的位置 25,201 处写入,但我不确定我在哪里指定了错误的长度。
  • 可能您的索引超出了输入向量的范围?

标签: c++


【解决方案1】:

我将这个 SO 问题发布到 Aquila GitHub 问题页面和库创建者的 got back an answerCredit goes to another issue 发现(好时机)。

简而言之:Aquila 使用的 FFT 库 OouraFFT 需要一个 2 的幂的向量大小,但如果不是这种情况,它不会抱怨,它只是在第一次调用 @987654323 时写入已释放的内存@。总结教训是,在堆上疯狂之前,始终断言您需要检查的条件。

【讨论】:

    猜你喜欢
    • 2015-03-08
    • 2017-07-17
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-15
    • 2011-08-04
    相关资源
    最近更新 更多