algorithm – XOR linked list implementation – Follow Up (2)

This question is a follow up (2) question to the XOR linked list implementation.XOR linked list implementation – Follow Up

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

struct StNode {
    int value;
    uintptr_t both;
}; 
typedef struct StNode StHexNode;

StHexNode *add(StHexNode *lastNode, int value)
{
    StHexNode *newNode = malloc(sizeof *newNode);
    newNode->value = value;
    
    //latest node's (both)=pointer value pointing previous node:
    newNode->both = (uintptr_t)lastNode; 
    //calculating previous node (both):
    lastNode->both = (uintptr_t)newNode ^ lastNode->both;
    return newNode;
}

StHexNode *get(StHexNode *headNode, unsigned int index)
{
    
    StHexNode *prevNode;
    StHexNode *currNode;
    uintptr_t tmp;
    
    if(index == 0)
        return headNode;
    
    //cur=1, prev=0
    currNode = (struct StNode *) ((headNode->both) ^ 0);
    prevNode = headNode;
    
    for(int i=2; i<=index; i++)
    {
        tmp = (uintptr_t)prevNode;
        prevNode = currNode;
        currNode = (struct StNode *) (currNode->both ^ tmp);
    }
    return currNode;
}

int free_list(StHexNode *headNode)
{
    StHexNode *prevNode;
    StHexNode *currNode;
    uintptr_t tmp;
    int ctr=0;
    
    //case: there is a only head node in the list
    if(headNode->both == 0) 
    {
        free(headNode);
        return ++ctr;
    }
    
    //prev=head, curr=second_node
    currNode = (struct StNode *) ((headNode->both) ^ 0);
    prevNode = headNode;
    
    while(currNode->both != (uintptr_t)prevNode)
    {
        tmp = (uintptr_t)prevNode;
        free(prevNode);
        ctr++;
        prevNode = currNode;
        currNode = (struct StNode *) (currNode->both ^ tmp);
    }
    //last node
    free(currNode);
    ctr++;
    
    return ctr;
}

int main(void) 
{
    unsigned int i;
    
    //I named first node as headNode, and last node as tailNode
    //create head node with both=0 since there is no previous node to it
    StHexNode *headNode = malloc(sizeof *headNode);
    StHexNode *tailNode = headNode; //last node pointer in the list
    
    //lets add 100 nodes after head
    //special handling of both value at head node
    for(headNode->both = 0, i=100; i<200; i++)
    {
        tailNode = add(tailNode, i);
        //printf("last node value:%dn", tailNode->value);
    }
    //get index=50 node value
    StHexNode *iNode = get(headNode, 50);
    printf( "result: %dn",  iNode->value);
    
    //free memory
    printf("we released %d listn", free_list(headNode));
   
}