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▒▒
From the man page
The
strcat()
function appends thesrc
string to thedest
string, overwriting the terminating null byte ('\0') at the end ofdest
, 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.