Does CondD API confd_free_hkeypath still need to be called after we have freed the keypath in another API "confd_free_value"?

Here is the function to get a point of confd_hkeypath_t:

confd_hkeypath_t *cgo_get_hkeypath(const char *xpath) {
    confd_hkeypath_t *kp;
    int rc = maapi_xpath2kpath(maapi_sd, xpath, &kp);

    if (rc != CONFD_OK) {
        return 0;
    } else {
        return kp;
    }
}

We then set the pointer to the value of a confd_tag_value_t. Our question is whether the returned keypath can be freed by the function as following:

void cgo_free_tag_values(confd_tag_value_t *valArr, int valArrLen) {
    if (valArrLen == 0) {
        return;
    }

    for (int i = 0; i < valArrLen; i++) {
        confd_free_value(&valArr[i].v);
    }
}

We have this question because there is a description in Confd 7.3 user guide says the returned keypath can easiest be done by calling confd_free_hkeypath.

We set the pointer to an array of confd_tag_value_t in the following codes:

  1. This is the function to allocate the array of confd_tag_value_t:

    confd_tag_value_t cgo_alloc_value_arr(int valArrLen) {
    return (confd_tag_value_t
    ) calloc(valArrLen, sizeof(confd_tag_value_t));
    }

  2. First we allocate the confd_tag_value_t array.

    valArr := C.cgo_alloc_value_arr(C.int(numElem))
    defer C.free(unsafe.Pointer(valArr))

  3. We set the value:

    op := C.CString(notification.PushCU.Changes[i].Operation)
    value := C.CString(notification.PushCU.Changes[i].Value) // it is freeed by cgo_free_tag_values
    C.cgo_create_push_change_update_chg(valArr, &valArrLen, target, op, value)
    C.free(unsafe.Pointer(op))

  4. Here is the definition of cgo_create_push_change_update_chg:

    void cgo_create_push_change_update_chg(confd_tag_value_t *valArr, int *i,
    confd_hkeypath_t *target, const char *op, const char *value) {
    CONFD_SET_TAG_XMLBEGIN(&valArr[*i], cn_pcu_change->tag, cn_pcu_change->ns);
    (*i)++;

    CONFD_SET_TAG_OBJECTREF(&valArr[*i], cn_pcu_change_target->tag, target);
    (*i)++;

    CONFD_SET_TAG_ENUM_VALUE(&valArr[*i], cn_pcu_change_operation->tag, 3);
    (*i)++;

    CONFD_SET_TAG_STR(&valArr[*i], cn_pcu_change_value->tag, value);
    (*i)++;

    CONFD_SET_TAG_XMLEND(&valArr[*i], cn_pcu_change->tag, cn_pcu_change->ns);
    (*i)++;

    return;
    }

At last we free them by call the free funtion mentioned before as following:

C.cgo_free_tag_values(valArr, valArrLen)

Would you please help check if we still need to call confd_free_hkeypath() to free the return keypath?

I believe you should not call the function - confd_free_value in case of a C_OBJREF value does pretty much exactly the same as what confd_free_hkeypath does. Iā€™m kind of getting lost in the Go-C binding code you post, but as far as I can tell you just pass the reference, so calling confd_free_hkeypath would cause a double-free error.

1 Like