Search code examples
cstringstructstrcat

Struct to String - strcat isn't working


I have a struct FRAME:

typedef struct frame{
   unsigned char type; 
   unsigned char seq;
   int size; 
   char *payload; 
}FRAME;

Than i have an array of FRAMES and i want to concatenate the first one:

    frames[0].type='d';
    frames[0].seq=seq;
    frames[0].size=(int)strlen(f);
    frames[0].payload=f;
    //check
    printf("%c\n",frames[0].type);
    printf("%c\n",frames[0].seq);
    printf("%d\n",frames[0].size);
    printf("%s\n",frames[0].payload);

    int num=sizeof(frames[0].type)+sizeof(frames[0].seq)+sizeof(frames[0].size)+strlen(frames[0].payload);
    printf("%d\n",num);
    char *m=malloc(num*sizeof(char));

    strcat(m,frames[0].type);
    strcat(m,frames[0].seq);
    strcat(m, frames[0].size);
    strcat(m, frames[0].payload);
    printf("%s",m);

But he gaves me "Segmentation fault in strcat"... Can someone help me with this?


Solution

  • The strcat function expects the destination to already contain a valid string, which means it should have a terminator character '\0'. When you use malloc it doesn't initialize the memory allocated at all, its content is indeterminate and reading that memory (which strcat does to find the terminator) leads to undefined behavior.

    There are also other serious problems, like you using the structure members as strings, which they are not! You simply can't use strcat or other similar functions (like strcpy). You could use e.g. snprintf but then you don't allocate enough memory to store all data in the structure, for example the size of an integer is four bytes, but it can contain ten digits (plus possible '-' for negative numbers).


    My proposed solution:

    size_t size = 1 + 1 + 11 + strlen(frames[i].payload) + 1;
    // 1 for type
    // 1 for seq
    // 11 for the integer (assuming it's 4 bytes)
    // strlen(...) for string
    // 1 for terminator
    
    char *m = malloc(size);
    snprintf(m, size, "%c%c%11.11d%s",
        frames[i].type,
        frames[i].seq,
        frames[i].size,
        frames[i].payload);