Search code examples
csegmentation-faultbuffermemmove

copy character string to an unsigned buffer: Segmentation fault


i am trying to copy two integers and a character string to a buffer and print the buffer elements out. I get a seg fault for the third printf statement:

    id = 102;
    len = 3;
    str = "working";
    memmove(buffer,&message_id,sizeof(id));
    memmove(buffer+(sizeof(id)),&len,sizeof(len));
    memmove(buffer+(2*sizeof(id)),&string, sizeof(str));

    printf("1 is: %d\n", buffer[0]);
    printf("2 is: %d\n", buffer[4]);
    printf("3 is %s\n, buffer[8])); // here is where i get the seg fault should
    be a string
    /***/
    bufer is declared as unsinged char buffer[444];

I dont know why this would seg fault?


Solution

  • There were several issues on your code, but the most important point is that memmove() does not copy the null character byte of the string.

    The function does not check for any terminating null character in source - it always copies exactly num bytes.

    This gives you two options:

    • Account for that while you are copying the stuff:

    memmove(buffer+sizeof(id)+sizeof(len), str, strlen(str) +1);

    • Or after the memory was copied, make sure the string ends with a '\0' (aka. 0) on your buffer:

    memmove(buffer+sizeof(id)+sizeof(len), str, strlen(str));

    buffer[sizeof(id)+ sizeof(len) + strlen(str) + 1] = 0;

    Anyway, the code works now. Another issue was that you were trying to specify the length of the string with sizeof(str). That's wrong, and you should be doing strlen(str). One last thing, for clarity and security purposes don't do 2*sizeof(id). If later you decide to change the variable type you are screwed. The right way wold be sizeof(id)+sizeof(len). That's all.

    int id = 102;
    int len = 3;
    char* str = "working";
    char buffer[444];
    
    memmove(buffer,&id,sizeof(id));
    memmove(buffer+(sizeof(id)), &len, sizeof(len));
    memmove(buffer+sizeof(id)+sizeof(len), str, strlen(str));
    buffer[sizeof(id)+ sizeof(len) + strlen(str) + 1] = 0;
    
    printf("1 is: %d\n", buffer[0]);
    printf("2 is: %d\n", buffer[4]);
    printf("3 is: %s\n", &buffer[8]);