По сути, проблема в том, что getAddress
имеет два доступа к указателю, который ему передан.
Когда вы вызываете getAddress(&headptr);
, происходит чтение headptr
(через параметр ptr
из getAddress
. Несколько операторов позже есть запись в headptr
. Между этим чтением и этой записью другой поток может иметь успешный _InterlockedCompareExchange64
, который изменяет значение headptr
. Когда это происходит, запись *ptr = temp;
изменит значение, сохраненное предыдущим потоком.
«Дешевое» исправление - getAddress
также выполняет блокированный обмен при записи в ptr
. Однако, почему getAddress
пишет вернуться к *ptr
вообще? Это кажется ненужным, если вы потеряете информацию о тегах, хранящуюся там.
Не связано, вызов build
в pop
ничего не делает, так как вы игнорируете возвращаемое значение.
И в вашем коде много неопределенного поведения, поскольку вы предполагаете, что используются только младшие 52 бита адреса. Такие вещи, как reinterpret_cast<Node*>(newptr);
, могут создавать плохие указатели, так как не указатель newptr
является вычислением значение ted, а не результат приведения из указателя.