Search code examples
pythongarbage-collectionctype

Python to C and Garbage Collector


I have the following problem in Python (problem with variable by ref or val in C)

My C Code:

#define NON_ALLOCATED 0
#define ALLOCATED 1
#define MAX_STACK 100

typedef struct myObject
{
   int iStatus;
   int iSize;
   double pdTab;
}

static myObject globaTab[MAX_STACK]

myObject *AllocateATab(int iSize)
{
   myObject *pxTab = NULL;
   int i;
   int iFound = 0;
   while(i < MAX_STACK && !iFound)
   {
      if (globaTab[i].iStatus = NON_ALLOCATED)
         iFound = 1;
         break;
   }
   if (i < MAX_STACK)
   {
      pxTab = globaTab + i;
      pxTab->iStatus = ALLOCATED;
      pxTab->pdTab = (double *)calloc(iSize, sizeof(double));
   }
   return pxTab;
}

int FreeATab(myObject *pxTab)
{
    if (pxTab)
    {
        pxTab->iStatus = NON_ALLOCATED;
        if (pxTab->pdTab)
           free(pxTab->pdTab);

    }
}

myObject *Scalar(double dValue)
{
    myObject *pxTab = AllocateATab(1000)
    for (int iSize = 0; iSize < 1000; iSize++)
       pxTab->pdTab[iSize] = dValue;

    return pxTab;

}

sample of my Python Code:

class MyClass(object):)
   def __del__(self):
      mylibC.FreeATab(self)

   def Scalar(valueinput):
      return mylibC.Scalar(valueinput)

   def transformValue(mylist):
        Len=len(mylist)
        res = [0]*Len
        for i in xrange(Len):
          if(type(mylist[i]) == float):
            res[i] = Scalar(mylist[i])
          else:
            res[i] = mylist[i]
        return res

    def myFunc(mylistlist):
        listValue = transformValue(mylist)
        return anotherCFunction(listValue)

When I use Scalar function status of myObject is equal to Allocated However when I enter in anotherCFunction I see that status of object List is now to NON_ALLOCATED because python garbage collector has been called due to Scalar(mylist[i]) is a local called

Could you please help me to rewrite this python code in order that Python does not called garbage collector on List[i] ? Thanks


Solution

  • I still don't think that there are garbage collection problems with the code you've posted so far. But there are other significant problems with your Python code. (FWIW, the C code looks ok, I suppose you have been using C for a while but are still fairly new to Python). The biggest problem is that the definition of MyClass is faulty. You haven't shown us the code where you create an instance of MyClass and how you use it, so there may be additional problems.

    When a class method is called it gets passed the class instance as the first argument, conventionally named self. This argument is not specified in the args given when you call the method but it must be specified in the method definition.

    Eg,

    class SimpleClass(object):
        def add(self, x, y):
            return x + y
    
    simple = SimpleClass()
    print simple.add_one(2, 3)  
    

    output

    5
    

    So the add() method is defined with three args, but when we call it we only supply two args explicitly, since the first arg, self, is implicit.

    Most of your method definitions do not have self as their first arg, apart from your __del__ method. Python doesn't care what you name your arguments, it will shove self into whatever is the first argument in the method's definition. So all your methods (apart from __del__) are getting called with wrong args.

    Also, when you call a method inside another method of that class you need to indicate that, normally by prefixing the method's name with self.. Eg

    def transformValue(self, mylist):
        #The rest of the method definition
        #...
    
    def myFunc(self, mylist):
        listValue = self.transformValue(mylist)
        return anotherCFunction(listValue)