When you allocate memory to an address, that memory persists, and is re-usable, until you free it.
For example:
char *buf1 = malloc(15);
strcpy(buf1, "15 characters."); //exactly 15 characters including NULL
|1|5| |c|h|a|r|a|c|t|e|r|s|.|\0|?|?|?|?|?|...
^ beginning and ^ end of allocated memory
If you allocate memory to another buffer with more memory than the first, and initialize it with the same content:
char *buf2 = malloc(20);
strcpy(buf2, "15 characters."); //exactly 15 characters including NULL
strcpy(buf1, buf2); //strcpy is successful, resulting memory is populated with:
|1|5| |c|h|a|r|a|c|t|e|r|s|.|\0|?|?|?|?|?|
But, if buf2
was created with much less content than buf1
, the remaining content of buf1
would remain, but would not be considered by any of the string functions as they look for the NULL terminator to determine end of string. For example:
char *buf2 = "short"; // contains 6 characters including NULL
strcpy(buf1, bu2); //strcpy is successful, and memory includes remnants old content
|s|h|o|r|t|\0|r|a|c|t|e|r|s|.|\0|?|?|?|?|?|
^^ end of new string, the rest is just artifact
Caution: some of the string functions ( such as strncpy ) will not always append a NULL character:
No null-character is implicitly appended at the end of destination if
source is longer than num.
To mitigate this, enough room must always be included for the NULL character if you need the resultant char array to be considered a C string, and in the case described above, you must explicitly append a NULL char to the end of the buffer. i.e., for strncpy()
:
strncpy (target, source, n);
target[n] = 0;
Another useful function when working with allocated memory is memset. It is a good practice when re-using the same buffer over several operations, to reset all positions in memory to NULL:
memset(buf1, 0, 15);//results in...
|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|