I could point you to man pages, websites, etc., but ultimately it is important that the C standard itself. As part of the standard runtime library, usage and behavior are defined in C99-Β§7.23.2.4 as follows :
#include <string.h> char *strncpy(char * restrict s1, const char * restrict s2, size_t n);
Description The strncpy function copies no more than n characters (characters that follow a null character are not copied) from the array pointed to by s2 to the array pointed to by s1. If copying occurs between overlapping objects, the behavior is undefined. If the array pointed to by s2 is a string that is shorter than n characters, null characters are added to the copy in the array pointed to by s1 until all n characters are written.
Returns The strncpy function returns the value s1.
There is significant implied information here: the most important of them: strncpy() will NOT terminate your target string with a null character if the length of the source string (not including its zero character terminator) meets or exceeds the specified length of the destination buffer).
In addition, although this is clearly indicated in the standard (see above), it continues to confuse me how many engineers DO NOT know that strncpy() tail fills the buffer of the target string with null characters until the specified length n is reached when the length of the original Lines are smaller than the size of the destination buffer. This makes the following undeniable conclusion:
The strncpy() API ALWAYS writes n characters to the address referenced by the destination buffer.
In your case, since the target buffer has a width of only 10 characters, you write 90 additional characters that have passed through a certain end of the recorded memory, and thus, go to the country of behavior undefined .
At this point, you should ask yourself: "So what to use?" There is perhaps a fundamental use case. It allows you to copy up to n characters into the target buffer with predictability, knowing that you will not overflow n characters. Period. Ultimately, however, you need a zero-terminated string, so the proper use is:
char dst[ N ]; strncpy(dst, src, N-1); dst[N-1] = 0;
where n is the fixed length of the dst buffer in characters and is greater than or equal to 1 . Note that dst can be the most dynamic allocated memory pointer possible:
char *dst = malloc( N * sizeof(char) ); strncpy(dst, src, N-1); dst[N-1] = 0;
With the above, you will always have a null-terminated string in dst . If the length of the source string is less than the specified length of the destination buffer, strncpy() will fill the rest of the buffer with null characters as long as the total number of characters with character-interpreted characters-character-characters is n , and the final statement is redundant. If the length of the source string is equal to or greater than the length of the destination buffer, strncpy() stop copying when the N-1 characters are reached, and the end statement sets the null character at the end of the buffer. This results in a prefix string to βcutβ the source source, but most importantly, it ensures that you DO NOT exceed the bounds of the destination buffer with a later call to the API string that the terminator scans.
The usefulness of the above method is always controversial. I'm a C ++ guy, so std::string keeps my happy self from all this madness. But the reality is this: sometimes you don't care if src not completely copied to dst ; sometimes you donβt do it. Utility is very situationally dependent. For presenting string data in the user interface, this will not (probably). For copying the string used for critical data, a partial prefix substring will not be acceptable. When the police issue an arrest warrant to Joseph Johnson Jr., there will be an explanation when his father (Joseph Johnson) will be sent to jail because the buffer name of the warrant software was only 15 characters long.
All of this, your segmentation error comes down to this statement:
strncpy(s1.from_str,src, 100);
Call up the bold statement above: " strncpy() will ALWAYS write n characters to the address pointed to by the destination buffer." . This means that the code above will always write 100 characters to the target buffer, which in your case has a width of only 10 characters, thus undefined behavior and probability of kera-boom .
Fix this by doing the following if the destination buffer is an array of characters of fixed length:
strncpy(s1.from_str,src, sizeof(s1.from_str)/sizeof(s1.from_str[0])-1); s1.from_str[ sizeof(s1.from_str)/sizeof(s1.from_str[0])-1 ] = 0;
See previous use for how to do this for a dynamic string of length `N characters.