To check if an address is 64 bits aligned, you just have to check if its 3 least significant bits are null. For instance
(ad & 0x7) == 0
checks if ad is a multiple of 8.
Addresses are allocated at compile time and many programming languages have ways to specify alignment. For instance, since CC++11 or C11, you can use alignas() in C++ or in C (by including stdalign.h) to specify alignment of a variable. Hence
alignas(8) char str[24];
guarantees that str is 64 bits aligned.
Before the alignas keyword, people used tricks to finely control alignment. For instance, a struct is aligned as its largest field. But there was no way, for instance, to insure that a struct with 8 chars or struct with a char and an int are 8 bytes aligned. Depending on the situation, people could use padding, unions, etc. This is no longer required and alignas() is the preferred way to control variable alignment.
Dynanically allocated data with malloc() is supposed to be "suitably aligned for any built-in type" and hence is always at least 64 bits aligned.
This can be used to move unaligned data to an aligned address. For instance, if you have a string str at an unaligned address and you want to align it, you just need to malloc() the proper size and to memcpy() data at the new position.
Note the std::align function in C++. Given a buffer address, it returns the first address in the buffer that respects specific alignment constraints and can be used to find a proper location in a buffer if variable reallocation is required.