Using malloc() and free() for a stack/linkedlist
On my answer to the question you are referencing, I state that “If
you use the heap like a stack (last in is first out), then it will
behave like a stack and not fragment.” This seems to be exactly your
usage pattern, thus you should not fear fragmentation. Of course, the
caveat written in Michel Keijzers’ answer applies: you should make sure
that no other part of your code, including libraries, is using
malloc() and free().

Just to give some evidence, the avr-lic documentation provides some
implementation details about malloc:


  When allocating memory [...] If nothing could be found on the
  freelist, heap extension is attempted. [...] When deallocating the
  topmost chunk of memory, the size of the heap is reduced.


All this can be seen in action in the source code of malloc() and
free(), which is abundantly commented and quite readable.



Edit 1: From the same section of the avr-libc documentation, we learn
about how realloc() grows a memory chunk:


  If [...] the old chunk is at the top of heap, and the above freelist
  walk did not reveal a large enough chunk on the freelist to satisfy
  the new request, an attempt is made to quickly extend this topmost
  chunk (and thus the heap), so no need arises to copy over the existing
  data.


Based on this, I would suggest you use an array, rather than a linked
list, and use realloc() to adjust the size of the array. A linked list
of n objects of size m has a memory cost n&nbsp;×&nbsp;(m+4):
each objects has an overhead of 2 bytes for the linking pointer, plus 2
bytes for malloc()'s internal bookkeeping. The cost of an array would
be only (n&nbsp;×&nbsp;m)+2.

In this case, however, it is essential that no other part of your code
uses malloc(), otherwise realloc() could end up allocating a whole
new array, which would be very costly.



Edit 2: I wrote a small test program that randomly grows and shrinks
a memory buffer. Running the test on an Uno shows that the allocated
memory chunk never changes address even though its size varies wildly.

void setup()
{
    Serial.begin(9600);
}

void loop()
{
    static void *p;
    static size_t sz;
    sz = random(max(sz, 22) - 20, min(sz + 20, 1536) + 1);
    p = realloc(p, sz);
    Serial.print((uintptr_t) p);
    Serial.print("  ");
    Serial.println(sz);
}