1

I created a data type which I want to send over a socket. I'm getting a compilation error and a segmentation fault error. The compilation error I get is error: invalid application of ‘sizeof’ to incomplete type ‘struct udp_msg_t’ whereas the segmentation fault happens when I do the memcpy. What am I doing wrong?

Here is some of my code:

This is the struct I'm concerned about which I defined:

typedef struct udp_msg {
    unsigned int udp_eid;
    u_char   udp_prefix;
    unsigned int udp_loc;
} udp_msg_t;

In a method I assign the memory and the values:

void method(){
    udp_msg_t * udp_msg;

    udp_msg = (struct udp_msg_t * )calloc(1, sizeof(struct udp_msg_t));
    udp_msg->udp_eid = eid.u.prefix4.s_addr;
    udp_msg->udp_prefix = eid.prefixlen;
    udp_msg->udp_loc = loc->rloc.rloc.s_addr;

    send_rloc_udp_to_floodlight(udp_msg);
}

And this method actually sends the data over a socket:

int send_rloc_udp_to_floodlight(udp_msg_t message) {
    struct sockaddr_in si_other;
    int s, i, slen = sizeof(si_other);
    char buffer[9];

    if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
        printf("socket");
    }

    memset((char *) &si_other, 0, sizeof(si_other));

    si_other.sin_family = AF_INET;
    si_other.sin_port = htons(8888);

    if (inet_aton("127.0.0.1", &si_other.sin_addr) == 0) {
        fprintf(stderr, "inet_aton() failed\n");
        exit(1);
    }


    memcpy(buffer, (char *) message.udp_eid, sizeof(unsigned int));
    memcpy(&buffer[4], (char *) message.udp_prefix, sizeof(char));
    memcpy(&buffer[5], (char *) message.udp_loc, sizeof(unsigned int));

    //send the message
    if (sendto(s, buffer, strlen(buffer), 0, (struct sockaddr *) &si_other,
            slen) == -1) {
        printf("sendto()");
    }

    close(s);
    return 0;
}
Paul R
  • 208,748
  • 37
  • 389
  • 560
Pheonix7
  • 2,131
  • 5
  • 21
  • 38

2 Answers2

2
sizeof(struct udp_msg_t)

is incorrect - it should be either

sizeof(udp_msg_t)

or

sizeof(struct udp_msg)

Ditto for the cast:

(struct udp_msg_t * )

in front of the call to calloc, although this should just be removed, since it's redundant and potentially dangerous.

Community
  • 1
  • 1
Paul R
  • 208,748
  • 37
  • 389
  • 560
  • Once your code compiles cleanly (no errors, no warnings, and make sure you use `gcc -Wall ...`) then if you still get a run-time error it's time to start debugging. See: [How to debug small programs](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/). – Paul R Feb 01 '16 at 10:15
  • 2
    Take Paul R's excellent advice. OP you should either use `sizeof(struct struct-name)` or use the name you've typedef'd the struct to have, in this case `udp_msg_t`. The typedef declares a new type called `udp_msg_t` which is equal to `struct udp_msg`. So writing `struct udp_msg_t` will make trouble. – Morten Jensen Feb 01 '16 at 10:15
1

I was not getting the pointer value of the struct field properly. The correct was to do the memcpy is:

memcpy(buffer, (char *) &message.udp_eid, sizeof(unsigned int));
Pheonix7
  • 2,131
  • 5
  • 21
  • 38