The autofree example uses the heap. It just makes calling free() automatic when the function returns, regardless of where it does so. It's leak protection.
It's also wrong since __attribute__((cleanup)) expects a function that takes an additional level of pointer. In this case, it'll call "free(&scratchpad);". Which doesn't get you a compiler warning in C because passing a char ** as a void * is perfectly fine. But your heap is f*cked after this.
Correct way to do it is
void free2(char **p)
{
free(*p);
}
#define autofree __attribute__((cleanup(free2)))