Question about strncpy documentation

Regarding strncpy : http://www.cplusplus.com/reference/clibrary/cstring/strncpy/ it mentions the following:

No null character is implicitly added to the end of the destination, so the assignment will only be null if the length of the string C in the source is less than num.

What is meant by this sentence?

+4
source share
6 answers

This means that, for example, if your source string contains 20 characters plus a zero delimiter, and your strncpy indicates less than 21 characters, the target string will not have a zero to it.

This is because of how it works: strncpy ensures that it will write exactly N bytes, where N is the length value passed to.

If the length of the source string (without the zero byte) is less than this, it will fill the destination area with zeros. If it is equal to or greater, you will not get the zero added to the destination.

This means that technically it cannot be the C string you get. This can be solved using code, for example:

 char d[11]; // Have enough room for string and null. strncpy (d, s, 10); // Copy up to 10 bytes of string, null the rest. d[10] = '\0'; // Then append null manually in case s was too long. 

You select 11 bytes (array indexes 0.10), copy up to 10 (indexes 0..9), then set the 11th (index 10) to zero.

Here is a diagram showing three ways to write strings of different sizes to a 10-digit area using strncpy (d, s, 10) , where . represents a null byte:

 sd ------------- ---------- Hello. Hello..... Hello Fred. Hello Fred Hello George. Hello Geor 

Note that in the second and third cases it is not written anywhere so that if you treat d as a string, you will probably be disappointed with the result.

+10
source

The string "foo" has 3 characters + 1 null terminator (it is stored as "foo\0" ), giving a total length of 4. If you call strncpy with n=3 (or less), it will not add a null terminator to the end target line, but will only copy "foo" . Attempting to print the resulting string will result in undefined behavior due to the absence of a null terminator that signals the end of the string.

You must be very careful with this and either go through n one more than the maximum source, or add a null limiter.

+5
source

This means that it copies the terminating zero of the source string, but does not add the terminating zero if the source string does not fit in the destination.

+4
source

The C lines are stored as char arrays, and they end in zero, which means that an extra 0 added at the end, which marks the end of the line and can be used later to find out the length of the line. Therefore, the string "hello" looks like this:

 char hello[] = {'h', 'e', 'l', 'l', 'o', 0}; 

Usually, when you copy a string, the null character should also be copied. Thus, the memory required for the string buffer is equal to the length + 1 (for example, (strlen(hello) + 1) * sizeof(char) ).

The strncpy function allows you to copy only as many characters as possible for placement in the provided buffer. If the buffer you provided is not large enough to hold this extra null , it will not be added. Or, if a string is cut, it will not be terminated by zero.

 char hello[] = "hello"; // 5 characters, 6 bytes long char hel[3]; strncpy(hel, hello, 3); // hel is {'h', 'e', 'l'} 

You should always be careful after calling strncpy , as the result may be an invalid C string. If the string does not end with zero, it is impossible to know its length, and most string manipulation functions will not work or will do something unexpected.

+4
source

This means that only num bytes will be copied from the source buffer to the destination buffer; therefore, if the length of the source string, if the top or equal to num , the terminating NULL byte will not be copied, and the result will not have the final byte NULL, which is dangerous.

It is recommended to use strlcpy .

+1
source

The semantics of strncpy() , even if it is explicitly explained in the C ++ link above, are widely misunderstood. The behavior of this function is incompatible and error prone.

To avoid problems when using it or later in the development process, when the maintainer will not read the code correctly and add more complex errors, there is a simple solution: NEVER USE THIS FUNCTION .

You can read more about this in this article by Bruce Dawson .

To answer your question: if the source string is longer than the size passed as the third argument (usually this corresponds to the size of the destination buffer), the function will copy the size characters to the destination and will not have a zero byte among these. Call strlen(destination); then it will invoke undefined behavior because it will try to read outside the array until it finds a null terminator. This specific behavior is what makes strncpy error-prone.

0
source

Source: https://habr.com/ru/post/1336587/


All Articles