Handling object* in large loops


#1

My apologies if this is obvious to anyone but me, but I have this piece of code in my extension files…

for (int ly = (height - 1); ly >= 0; ly--) {
    for (int lx = 0; lx < width; lx++) {
      if ((lx < (aw+offx)) && (ly < (ah+offy)) && (lx >= offx) && (ly >= offy)) {
        ox = number(lx-offx);
        oy = number(ly-offy);
        oyy = cons(oy, NULL);
        subscripts = cons(ox, oyy);
        element = getarray(array, subscripts, env, &bit);
        *element = number(readBGR(file));

        myfree(subscripts);
        myfree(oyy);
        myfree(oy);
        myfree(ox);
      }
      else {
        file.read();
        file.read();
        file.read();
      }
    }
    //ignore trailing zero bytes
    if (zpad > 0) {
      for (int i = 0; i < zpad; i++) {
        file.read();
      }
    }
  }

… where ox, oy, oyy and subscripts are declared as object* / object**. Is it necessary or even a mistake to use myfree on these in each iteration? Could/should I just mutate and thus re-use the pointers and omit myfree? Note that I need to cons oyy and subscripts for every pixel position.


#2

It’s definitely not obvious!

I never call myfree() directly; in fact it’s only called once in uLisp, from within the garbage collector. Unused conses will get garbage collected automatically. There might be an argument that calling myfree() manually will make the subsequent garbage collection quicker. However, it requires you to think about when variables are no longer needed, which to me removes the possible benefit.


#3

Thanks for stepping in! So if I get you right: It doesn’t cause havoc when I do without myfree in these nested loops, even when thousands of objects are allocated and abandoned again in quick succession? Maybe that even prevents heap fragmentation?


#4

That’s what garbage collection frees you from having to worry about. And there’s no fragmentation because the Lisp objects are all the same size.


#5

Got it now, thank you!


#6