From the document you linked:
int lfstack_pop(_Atomic lfstack_t \*lfstack)
{
lfstack_t next;
lfstack_t orig = atomic_load(lfstack);
do
{
if (orig.head == NULL) // undefined behavior !!!
{
return -1;
}
next.head = orig.head->next;
} while (!atomic_compare_exchange_weak(lfstack,&orig,next));
free(orig.head);
return 0;
}
If the first thread is preempted before the if(...) is executed, and then the second thread executes the entire method, then you will use data after freeing when the first thread resumes. Consider why the boost container doesn't free memory.