zeeMonkeez
zeeMonkeez

Reputation: 5157

Tcl_Format memory usage

Here is an extension proc for TCL written in C(++) (that it's C++ does not matter here – I just use std::vector). I use Tcl_Format to create a new formatted string. If I don't use Tcl_DecrRefCount, Xcode reports more and more memory being used every time this external proc is called:

int TclME::vTestExt(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj* const objv[])
{
    Tcl_Obj *resultPtr, *item[1], *itemFormatted;
    size_t N;
    std::vector<long> v;
    populate_v(v);
    N = v.size();
    resultPtr = Tcl_NewListObj(0, NULL);
    for (long i = 0; i < N; ++i) {
        item[0] = Tcl_NewLongObj(v[i]);
        printf("item[0] ref %i, sh %i; ", item[0]->refCount, Tcl_IsShared(item[0]));
        itemFormatted = Tcl_Format(interp, "#%06X", 1, item);
        // With Tcl_DecrRefCount commented out, there is a memory leak
        printf("\tref %i, sh %i; ", item[0]->refCount, Tcl_IsShared(item[0]));
        Tcl_DecrRefCount(item[0]);
        printf("\tref %i, sh %i\n", item[0]->refCount, Tcl_IsShared(item[0]));

        Tcl_ListObjAppendElement(interp, resultPtr, itemFormatted);
    }
    Tcl_SetObjResult(interp, resultPtr);
    return TCL_OK;
}

void populate_v(std::vector<long> &v) sets the vector items.

The output is item[0] ref 0, sh 0; ref 0, sh 0; ref -1, sh 0, so I would not expect having to call Tcl_DecrRefCount manually.

What did I miss?

Upvotes: 1

Views: 94

Answers (1)

Ctx
Ctx

Reputation: 18420

When you create a new TCL object, its reference count is 0.

Any TCL object is subject to be freed when the reference counter drops to 0. So, the clean way would be to first increment the reference counter after creating the object and then decrement it again when it is no longer being used (after the call to Tcl_Format() for example).

In your special case above, you can circumvent this problem by using Tcl_ObjPrintf():

...
for (long i = 0; i < N; ++i) {
    Tcl_ListObjAppendElement(interp, resultPtr, Tcl_ObjPrintf("#%06X", v[i]));
}
...

Upvotes: 3

Related Questions