memory management with t_linklist

Connector's icon

For a jitter MOP external i want to use two matrices as input and two matrices as output. For the output matrices i want to calculate some values and store it into a t_linklist for sorting the values wich are of the type connector_linesAB:

typedef struct
{
    float x;
    float y;
    float z;
} connector_point_Vec3;

typedef struct
{
    connector_point_Vec3 facePoint;
    long faceIndex;
    connector_point_Vec3 singlePoint;
    long singleIndex;
    float length;
} connector_linesAB;

The sorting and calculation of the output matrices should be done in the matrix_calc function:

t_jit_err connector_lines_matrix_calc(t_connector_lines* x, void* inputs, void* outputs)
{
    t_jit_err err = JIT_ERR_NONE;
    t_linklist* linesList = linklist_new();

    t_jit_matrix_info in_minfo, in2_minfo, out_minfo, out2_minfo;
    void *in_matrix, *in2_matrix, *out_matrix, *out2_matrix;
    char* in_bp, * in2_bp;
    float* indata, *indata2, *pospointer1, *pospointer2;
    long in_savelock, in2_savelock, out_savelock, out2_savelock;
    in_matrix = jit_object_method(inputs, _jit_sym_getindex, 0);
    in2_matrix = jit_object_method(inputs, _jit_sym_getindex, 1);

    out_matrix = jit_object_method(outputs, _jit_sym_getindex, 0);
    out2_matrix = jit_object_method(outputs, _jit_sym_getindex, 1);   

    if (x && in_matrix && in2_matrix && out_matrix && out2_matrix) {

        in_savelock = (long)jit_object_method(in_matrix, _jit_sym_lock, 1);
        in2_savelock = (long)jit_object_method(in2_matrix, _jit_sym_lock, 1);
        out_savelock = (long)jit_object_method(out_matrix, _jit_sym_lock, 1);
        out2_savelock = (long)jit_object_method(out_matrix, _jit_sym_lock, 1);

        jit_object_method(in_matrix, _jit_sym_getinfo, &in_minfo);
        jit_object_method(in2_matrix, _jit_sym_getinfo, &in2_minfo);
        jit_object_method(out_matrix, _jit_sym_getinfo, &out_minfo);
        jit_object_method(out2_matrix, _jit_sym_getinfo, &out2_minfo);
  
        jit_object_method(in_matrix, _jit_sym_getdata, &in_bp);
        jit_object_method(in2_matrix, _jit_sym_getdata, &in2_bp);
       
        if (!in_bp || !in2_bp) { err = JIT_ERR_INVALID_INPUT; goto out; }
        
        indata = (float*)(in_bp);
        indata2 = (float*)(in2_bp);
       
        for (int i = 0; i < (&in_minfo)->dim[0]; i++) {
            long offsetFacePoint = (&in_minfo)->dimstride[0] * i;
            pospointer1 = (float*)(in_bp + offsetFacePoint);
            connector_point_Vec3 facePoint;
            facePoint.x = pospointer1[0];
            facePoint.y = pospointer1[1];
            facePoint.z = pospointer1[2];

            for (int j = 0; j < (&in2_minfo)->dim[0]; j++) {

                long offsetSinglePoint = (&in2_minfo)->dimstride[0] * j;
                pospointer2 = (float*)(in2_bp + offsetSinglePoint);
                connector_point_Vec3 singlePoint;
                singlePoint.x = pospointer2[0];
                singlePoint.y = pospointer2[1];
                singlePoint.z = pospointer2[2];
                             
                connector_linesAB* newLine = (connector_linesAB*) sysmem_newptr(sizeof(connector_linesAB));
                newLine->faceIndex = i;
                newLine->facePoint = facePoint;
                newLine->singleIndex = j;
                newLine->singlePoint = singlePoint;
                newLine->length = distance(facePoint, singlePoint);

                linklist_append(linesList, newLine);
            }

        }
        
        linklist_sort(linesList, mySortListCmpfn);

        connector_linesAB* data;
        long i, count;
        long maxSinglePoints = 5;
        count = linklist_getsize(linesList);
        for (i = 0; i < maxSinglePoints; i++) {
            data = (connector_linesAB*)linklist_getindex(linesList, i);
            post("length=%f", data->length);
        }
         
        jit_object_method(out_matrix, _jit_sym_frommatrix, in_matrix, NULL);
        jit_object_method(out2_matrix, _jit_sym_frommatrix, in2_matrix, NULL);   
        
    }
    else {
        return JIT_ERR_INVALID_PTR;
    }

out:
    object_free(linesList);
    jit_object_method(out2_matrix, _jit_sym_lock, out2_savelock);
    jit_object_method(out_matrix, _jit_sym_lock, out_savelock);
    jit_object_method(in2_matrix, _jit_sym_lock, in2_savelock);
    jit_object_method(in_matrix, _jit_sym_lock, in_savelock);
    return err;
}

The memory allocation, adding Values and sorting the list seems to work but at the end of the matrix_calc function i want to free the memory with the object_free function. When i call the object_free function with the t_linklist i got following error messages:

bad object while free linklist

So how do i do the right memory managment with t_linklist and my own struct types?

Rob Ramirez's icon

I think you should be using linklist_chuck or linklist_clear rather than object_free on your linklist. And you also should specify that you are storing data rather than objects by calling linklist_flags(linesList, OBJ_FLAG_DATA) or linklist_flags(linesList, OBJ_FLAG_MEMORY), depending on if you want the memory freed or not, after constructing your linklist.

OBJ_FLAG_DATA = 0x00000002, ///< don't free data or call method
OBJ_FLAG_MEMORY = 0x00000004, ///< don't call method, and when freeing use sysmem_freeptr() instead of freeobject

Connector's icon

Thanks for the answer. Does work now..