I'm writing a UDP socket program which is provided an address from the command line.
To make sending and writing easier, I'm using getaddrinfo to convert the address to a sockaddr struct: either sockaddr_in or sockaddr_in6. Now I understand that I should use a union of sockaddrs:
typedef union address
{
    struct sockaddr s;
    struct sockaddr_in s4;
    struct sockaddr_in6 s6;
    struct sockaddr_storage ss;
} address_t;
As I understand they can't be pointers to avoid hiding strict aliasing problems. I'm having trouble seamlessly putting the information from getaddrinfo's addrinfo into this address_t:
struct addrinfo hint, *serv = NULL;
address_t addr;
hint.ai_family = AF_UNSPEC;
hint.ai_flags = 0;
hint.ai_socktype = SOCK_DGRAM;
hint.ai_protocol = IPPROTO_UDP;
ret = getaddrinfo(address_sr.c_str(), s_port.c_str(), &hint, &serv);
//address_sr and s_port are strings with the address and port
switch (serv->ai_addr) {
    case AF_INET: {
        addr->s4 = * (sockaddr_in*) serv->ai_addr;
        //Here I want to fill the address_t struct with information
        //This line causes a segfault 
    }
    break;
    case AF_INET6: {
        addr->s6 = * (sockaddr_in6*) serv->ai_addr;
        //Conversion here
    }
    break;
Also, copying the memory:
    memcpy(&addr, serv->ai_addr, serv->ai_addrlen);
Causes a segfault too.
How exactly should I do this? I tried a dozen different ways and I just can't figure it out. How do I put an address from addrinfo to this union? Do I use sockaddr_storage or the sockaddr_ins?
EDIT: Editing for clarity and additional code information.