0

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▒▒

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261

1 Answers1

2

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.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • Thanks a lot, seems like I don't have solid foundation at all. Not just gave me the solution and also the method how to generate it, amazing! – Jack Nanray May 19 '19 at 08:43