One of the solutions which often turns up in several posts on how to determine if a void * points to aligned memory involves casting the void pointer. That is say I get a void *ptr = CreateMemory() and now I want to check if memory pointed to by ptr is a multiple of some value, say 16. 
See How to determine if memory is aligned? which makes a specific claim.
A pointer p is aligned on a 16-byte boundary iff ((unsigned long)p & 15) == 0.
A solution in a similar vein appears in this post. How to check if a pointer points to a properly aligned memory location?
Can someone clarify, how does this casting work? I mean, if I had a void *ptr = CreateMem();, it seems to me that (unsigned long)(ptr) would give me the pointer itself reinterpreted as an unsigned long. Why would the value of this reinterpreted void pointer have any bearing on the alignment of the memory pointed to?
EDIT: Thanks for all the useful comments. Please bear with me a bit more. Perhaps a simplified example will help me understand this better.
#include <iostream>
using namespace std;
struct __attribute__((aligned(16))) Data0 {
  uint8_t a;  
};
struct Data1 {
  uint8_t a;  
};
int main() {
    std::cout<<sizeof(Data0) << "\n"; //< --(1)
    std::cout<<sizeof(Data1) << "\n";
    Data0 ptr0[10];
    Data1 ptr1[10];
    std::cout<<(unsigned long) (ptr0 + 1) - (unsigned long) ptr0   << "\n"; //< --- (2)
    std::cout<<(unsigned long) (ptr1 + 1) - (unsigned long) ptr1   << "\n";
    return 0;
}
To date, I always interpreted aligned memory to have the following two requirements. sizeof() should return a multiple of the the specified size (See condition (1)). And the while incrementing a pointer to aligned struct array, the stride would end up also being a multiple of the specified size (See condition (2)). 
So I am somewhat surprised to see there is a third requirement on the actual value of ptr0 as well. Or I might have misunderstood this entirely. Would the memory pointed to by ptr0 in the above example be considered aligned and not so for ptr1?
As I am typing this, I realize I do not actually understand what aligned memory itself means. Since I have mostly dealt with this while allocating cuda buffers, I tend to relate it to some sort of padding required for my data structs.
Consider a second example. That of aligned_alloc. https://en.cppreference.com/w/c/memory/aligned_alloc
Allocate size bytes of uninitialized storage whose alignment is specified by alignment.
I am not sure how to interpret this. Say, I do a void *p0 = aligned_alloc(16, 16 * 2), what is different about the memory pointed to by p0 as compared to say p1 where std::vector<char> buffer(32); char *p1 = buffer.data().
 
     
    