Search code examples
c++socketsreinterpret-cast

Why reinterpret_cast fails while memcpy works?


I'm writing some socket code and based on some params I'm using either IPv4 or IPv6. For that I have a code like this:

struct sockaddr final_addr;
...
struct sockaddr_in6 addr6;
... 
memcpy(&final_addr, &addr6, size);
...
bind(fd, &final_addr, size);

This works fine. However if I do (which was my initial idea)

struct sockaddr final_addr;
...
struct sockaddr_in6 addr6;
... 
final_addr = *reinterpret_cast<struct sockaddr*>(&addr6);
...
bind(fd, &final_addr, size);

then it fails on bind with Cannot assign requested address error.

Note that this incorrect code works fine if I switch to IPv4's sockaddr_in.

What's going on here? Why can't I just reinterpret sockaddr_in6 as sockaddr?


Solution

  • If in the first version of the code size is sizeof(addr6) (as you stated in the comments), then the first version of the code uses memcpy to copy sizeof(struct sockaddr_in6) bytes of data.

    The second version of the code uses regular struct sockaddr assignment to copy only sizeof(struct sockaddr) bytes.

    sizeof(struct sockaddr) is smaller than sizeof(struct sockaddr_in6), which makes these two code samples different.

    Note that in the first version the recipient object in that memcpy is of struct sockaddr type, i.e. it is smaller than the number of bytes copied. Memory overrun occurs, which clobbers some other data stored in adjacent memory locations. The code "works" only by accident. I.e. if this bit "works", then some other piece of code (the one that relies on the now-clobbered data) is likely to fail.