MYF

Confusing Functions in string.h

As we all know, there are multiple useful functions in string.h. For safety purpose, it requires the parameter n to limit the size in preventing hacks. In this post, we are going to talk about a few functions which is really helpful but also confusing in string.h library.

strndup

Description in manual: The strdup() function returns a pointer to a new string which is a duplicate of the string s. Memory for the new string is obtained with malloc(3), and can be freed with free(3). The strndup() function is similar, but copies at most $n$ bytes. If $s$ is longer than $n$, only $n$ bytes are copied, and a terminating null byte '\0' is added.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
const char * s = "1234567";
char * s1 = strndup(s, 6);
printf("%s\n", s1);

char * s2 = strndup(s, 10);
printf("%s\n", s2);
free(s1); // 7 bytes is freed.
free(s2); // 8 bytes is freed.
return EXIT_SUCCESS;
}

In this example, we can find that, if you ask for a length which is shorter than strlen(s), it will allocate strlen(s) + 1 bytes.

Conclusion: We can use char * dest = strndup(src, strlen(src)); to request memory and deep copy the string and return the string pointer.

strncpy

Description in manual: The strcpy() function copies the string pointed to by src, including the terminating null byte (\0), to the buffer pointed to by dest. The strings may not overlap, and the destination string dest must be large enough to receive the copy. Beware of buffer overruns! (See BUGS.) The strncpy() function is similar, except that at most $n$ bytes of src are copied. Warning: If there is no null byte among the first $n$ bytes of src, the string placed in dest will not be null-terminated.

1
2
3
4
5
6
7
8
9
10
char * strncpy(char *dest, const char *src, size_t n){
size_t i;

for (i = 0; i < n && src[i] != '\0'; i++)
dest[i] = src[i];
for ( ; i < n; i++)
dest[i] = '\0';

return dest;
}

This function only ensures the first $n$ bytes of dest will be set, but it does not promise a null terminator.

Conclusion: The safest way to use this function is that, call strncpy(dest, src, n-1) to copy the first n-1 letters of src, and then dest[n-1] = '\0'; to add a null terminator manually, where n indicates how many bytes dest takes up.

strncmp

Description in manual: The strcmp() function compares the two strings s1 and s2. It returns an integer less than, equal to, or greater than zero if s1 is found, respectively, to be less than, to match, or be greater than s2. The strncmp() function is similar, except it compares only the first (at most) n bytes of s1 and s2.

Return value in manual: The strcmp() and strncmp() functions return an integer less than, equal to, or greater than zero if s1 (or the first n bytes thereof) is found, respectively, to be less than, to match, or be greater than s2.

Conclusion: It only compares the first(at most) n bytes of s1 and s2, the return value is the ASCII difference of the first different letter with the same position in the strings.