Search code examples
cpointersmallocfreedynamic-memory-allocation

[strcat&malloc&free], when I use strcat(), pointer seems not NULL even I deliberately made it to be(no extra assignment)?


as the title, I made a demo to describe my confusion.

if I replace [strcat ]to [stacpy], I can get what's obvious, which is

@

@

@

so I suspected the problem comes up with [strcat].

void main(){
    for(int i=0; i<3 ;i++){

        char* str = (char*)malloc(200*sizeof(char));

        if(str == NULL){
            printf("malloc failed. \n");
            return;
        }

        strcat(str, "@ ");
        printf("%s\n", str);

        free(str);
        str = NULL;
    }
}

In my expectation, I should get:

@

@

@


but what I got is:

(1) @

xK`▒

xK`▒

and every time are not the same:

(2) @

x▒

x▒

(3) @

xk▒▒

xk▒▒


Solution

  • From the man page

    The strcat() function appends the src string to the dest string, overwriting the terminating null byte ('\0') at the end of dest, and then adds a terminating null byte. [...]

    Note the emphasis, the first argument, the destination, should be a string.

    The problem is, malloc() does not return the pointer to memory block which is initialized. So, there's no guarantee that there is a null-terminator anywhere in the returned memory block. So, in search of the null-terminator, your program will access past the allocated memory, and attempt to access invalid memory location, which invokes undefined behavior or UB. You said

    and every time are not the same:

    that's what UB is precisely.

    Related, from C11, chapter §7.22.3.4

    The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate.

    You should use calloc() if you want to use the returned pointer as string, as the memory block is zero-initialized.