-1

I am currently trying to implement an external for Pure Data using C. I've not been using C for a while, and I have a memory corruption problem. I don't know what to do, so I'm asking for your help.

Here is the code. Please remember that it is a C code for Pure Data.

t_int           *myfft_tilde_perform(t_int *w) {

    t_myfft_tilde *fft = (t_myfft_tilde *)w[1];
    t_float *in = (t_float *)w[2];
    t_float *out = (t_float *)w[3];
    int n = (int)w[4];

    int i;
    for(i=0; i<n; i++)
    {
        fft->bigbuffer[fft->nextindex] = in[i];
        fft->nextindex = (fft->nextindex+1)%TAILLE;
    }

    if (!fft->isfull && fft->nextindex==0)
    {
        fft->isfull=1;
    }

    if (fft->isfull)
    {

        for(i=0; i<TAILLE; i++)
        {
            fft->bigbuffercpy[i] = fft->window[i] * fft->bigbuffer[i];
        }

        rdft(TAILLE, 1, fft->bigbuffercpy, fft->bitshuffle, fft->weighting);

        if (fft->nextindex==0)
        {
            i=(TAILLE-1)-64;
        }
        else
        {
            i=fft->nextindex-64;
        }
        int j;
        for(j=0; j<64; j++)
        {
            out[j] = fft->bigbuffercpy[i+j];
        }
    }

    return (w+5);

}

void            myfft_tilde_dsp(t_myfft_tilde *x, t_signal **sp) {

    dsp_add(myfft_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);

}

void            myfft_tilde_free(t_myfft_tilde *x) {

    if (x->bitshuffle)
        freebytes(x->bitshuffle, TAILLE*2*sizeof(int));
    if (x->weighting)
        freebytes(x->weighting, TAILLE*2*sizeof(float));
    if (x->window)
        freebytes(x->window, TAILLE*sizeof(float));
    if (x->bigbuffer)
        freebytes(x->bigbuffer, TAILLE*sizeof(float));
    if (x->bigbuffercpy)
        freebytes(x->bigbuffercpy, TAILLE*sizeof(float));

}

void            *myfft_tilde_new(void) {

    t_myfft_tilde *fft = (t_myfft_tilde *)pd_new(myfft_tilde_class);

    fft->x_out = outlet_new(&fft->x_obj, &s_signal);

    fft->bitshuffle = (int *)calloc(TAILLE*2, sizeof(int));
    fft->weighting = (float *)calloc(TAILLE*2, sizeof(float));
    fft->window = (float *)calloc(TAILLE, sizeof(float));
    fft->bigbuffer = (float *)calloc(TAILLE, sizeof(float));
    fft->bigbuffercpy = (float *)calloc(TAILLE, sizeof(float));

    int i;
    for(i=0; i<TAILLE; i++)
    {
        fft->window[i] = 0.54 - 0.46*cos(TWOPI*i/TAILLE);
    }

    fft->nextindex=0;
    fft->isfull=0;

    init_rdft(TAILLE*2, fft->bitshuffle, fft->weighting);

    return (void *)fft;
}

void            myfft_tilde_setup(void) {

    myfft_tilde_class = class_new(gensym("myfft~"),
                              (t_newmethod)myfft_tilde_new,
                              (t_method)myfft_tilde_free,
                              0, sizeof(t_myfft_tilde),
                              CLASS_DEFAULT, A_GIMME, 0);
    CLASS_MAINSIGNALIN(myfft_tilde_class, t_myfft_tilde, f);
    class_addmethod(myfft_tilde_class, (t_method)myfft_tilde_dsp,
                gensym("dsp"), 0);

}

The functions that you don't know are functions that have been given to me. The memory corruption error occurs this way : I compile the code using a given makefile, then I try to run a given Pure Data file using the resulting pd_linux file in my console, and I immediately get this message in the console :

*** Error in `puredata': malloc(): memory corruption: 0x084f4570 ***
Pd: signal 6

I tried even to remove all the calloc I've done, but the error still occurs...

Max N
  • 1,134
  • 11
  • 23
DieNah
  • 11
  • 1
  • Please [do not cast](http://stackoverflow.com/q/605845/2173917) the return value of `malloc()`/ `calloc()`. – Sourav Ghosh Jan 06 '15 at 13:14
  • What is `TAILLE` ? and: is it larger than 64 ? – joop Jan 06 '15 at 13:14
  • I cannot make out what this code does, but I suggest you start debugging. You can step through the code to see where the error is thrown, or you can "downscale" the code and go from an empty extension, gradually adding stuff (and gradually increasing memory use) until the error occurs again. Then you know where the error is. – Paul Ogilvie Jan 06 '15 at 13:44
  • Casts removed. But the error remains :/ – DieNah Jan 06 '15 at 16:03
  • TAILLE is the size of the big buffers. Its value is currently 1024. Puredata only deals with 64 bytes buffer, which is too small to deal with sound (which is the purpose of this program), so I have to use bigger buffers to make the data more relevant during the computations. – DieNah Jan 06 '15 at 16:06
  • I will try your second option Paul. Indeed I tried to debug. It seems that the error occur at the outlet creation : fft->x_out = outlet_new(&fft->x_obj, &s_signal); – DieNah Jan 06 '15 at 17:47
  • What's the casting-gore at the beginning of the function supposed to do? It looks *remarkably* suspicious, particularly without the struct definitions/typedefs. – EOF Jan 06 '15 at 21:05
  • It's not an ordinary C program, it's a Puredata thing... I know it's not really sexy, but that's the way to do it [http://pdstatic.iem.at/externals-HOWTO/pd-externals-HOWTOse5.html#x7-290005] – DieNah Jan 07 '15 at 10:02

1 Answers1

2

you are using class_new() wrongly.

it's arguments are:

  • name
  • constructor
  • destructor
  • size of the member-data struct
  • flags
  • arg-specification for the constructor
  • a 0 (terminator)

you have swapped size and flags, giving an effective size of 0 bytes. pd_new() will then allocate 0 (zero, naught) bytes for your fft-struct, which leads to a memory corruption once you access the struct members (as you do in the next line).

apart from that: please always use t_sample instead of t_float (or float!!) for sample values. always use t_float instead of float for message numbers.

umläute
  • 28,885
  • 9
  • 68
  • 122