kfrlib / kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
https://www.kfrlib.com
GNU General Public License v2.0
1.67k stars 256 forks source link

convolve_filter destructor heap corruption #14

Closed debrowne closed 7 years ago

debrowne commented 7 years ago

I am having sporadic issues with convolve_filter, which has been causing heap corruption errors when its destructor is called. I have implemented it in a simple wrapper class that constructs FIR filters and filters signals:

template<typename T, size_t size>
struct MP_FIR_c {

kfr::univector<T, size> IR;
kfr::convolve_filter<T> cfilt;

MP_FIR_c(const char* fname) : 
cfilt(size, size)
{
    std::fill(IR.begin(), IR.end(), 0.0f);
    FILE* filter = fopen(fname, "r");
    char c_buffer[20];
    size_t index = 0;
    while (fgets(c_buffer, 20, filter)) {
        IR[index] = atof(c_buffer);
        ++index;
    }
    fclose(filter);
    cfilt.set_data(IR);
}

MP_FIR_c(const MP_FIR_c& from) :
    IR(from.IR),
    cfilt(IR, size)
{ }

MP_FIR_c(const std::vector<T>& from) :
    IR(from),
    cfilt(IR, size)
{ }

~MP_FIR_c() { 
};

/* filter using FFT overlap-add - destructive edit on in*/
template<size_t tag>
void overlap_add(kfr::univector<T, tag>& in) {
    cfilt.apply(in);
}

/* filter using FFT overlap-add - outputs to a new vector dest*/
template <size_t s1, size_t s2>
void overlap_add(kfr::univector<T, s1>& dest, const kfr::univector<T, s2>& src) {
    cfilt.apply(dest, src);
};

void overlap_add(double* sig, size_t size) {
    kfr::univector<double, 0> sig_vec(sig, size);
    cfilt.apply(sig_vec);
};

/* filter using time-domain convolution */
void convolve(kfr::univector<T>& dest, const kfr::univector<T>& src) {
    dest = fir(src, IR);
}

    /* OTHER METHODS VV */
};

The usage is typically along the lines of:

     double* sig = new double[sigSize];
     // read signal into sig
     MP_FIR_c<double, 8192> filter(filterFname);
     filter.overlap_add(sig, sigSize);

The error is not 100% consistent and I cannot figure out what could cause it. It happens when I call convolve_filter methods on other objects as well - not just instances of this class. I can sometimes get the error to temporarily go away by changing the block_size of the convolve_filter, but other times it works fine with the block_size equal to the size of the filter. In any case, the filtering is usually performed appropriately, and the heap corruption error appears when the convolve filter destructor is called.

stack trace: KFR ConvolveFilter heap corruption call stack.txt

Environment: Windows 10 Visual Studio 2015 LLVM-vs2014 / Clang 5.0

dancazarin commented 7 years ago

Hi, Function shown in the error message isn't the function caused heap corruption, it's the function detected it. Corruption itself happened somewhere before call to this function. The free function called inside convolve_filter destructor has detected heap corruption that happened before, anywhere in the code or in any used library. The most frequent cause of heap corruption is writing an array out of its bounds. Try to find minimal code that reproduces this issue. And check that index variable never exceeds size parameter, because in that case IR array will be written out of bounds.