Whether something is unaligned or not depends on the data type and its size As the answer from Gregg explains.
A well-written program usually does not have unaligned memory access, except when the compiler introduces it. (Yes, that happens during vectorization but let's skip that).
But you can write program in C++ to force unaligned memory access. The code below does just that.
#include <iostream>
using namespace std;
int main() {
int a[3] {1, 2, 3};
cout << *((long long *)(&a[0])) << endl;
cout << *((long long *)(&a[1])) << endl;
cout << (long long) (&a[0]) << endl;
cout << (long long) (&a[1]) << endl;
return 0;
}
The output of the code is this
8589934593
12884901890
70367819479584
70367819479588
What this program does?
I declare an integer array of size 3. This array will be 4 byte aligned because int is a 4 byte data type (at least on my platform). So the address of a[0] is divisible by 4. Now address of both of a[0] and a[1] is divisible by 4 but only address of one of them is divisible by 8.
So if I cast the address of a[0] and a[1] to a pointer to long long (which is an 8 byte data type on my platform) and then deference these two pointers, one of them will be an unaligned memory access. This is not undefined behavior AFAIK, but it is going to be slower than aligned memory access.
As you see this code contains C style casts which is not a good practice. But I think for enforcing some strange behavior that is fine.
let me know if you have question about the output of the code. You should know about endianness and representation of integers to understand the first two lines. The third and fourth line are address of the first two elements of the integer array. That should be easier to understand.