开发者

When to use strncpy or memmove?

开发者 https://www.devze.com 2022-12-31 11:50 出处:网络
(gcc 4.4.4 c89) I have always used strncpy to copy strings. I have never really used memmove or memcpy very much. However, I am just wondering when would you decide whether to use strncpy, memmove, o

(gcc 4.4.4 c89)

I have always used strncpy to copy strings. I have never really used memmove or memcpy very much. However, I am just wondering when would you decide whether to use strncpy, memmove, or memcpy?

The code I am writing is for a client/server application. In the documentation they use bcopy. However, could I do the same with the others?

bcopy((char*)server->h_addr,
      (ch开发者_JS百科ar*)&serv_addr.sin_addr.s_addr,
      server->h_length);

Many thanks,


strncpy() is used to copy data from a source to a dest of a set size, copying (padding) 0x00s if a 0x00 byte is found in the source array (string) before the end of the buffer. As opposed to strcpy which will blissfully copy forever until a 0 byte is found - even if said byte is well beyond your buffer.

memcpy() is used to copy from source to dest no matter what the source data contains. It also tends to be very hardware optimized and will often read system words (ints/longs) at a time to speed up copying when alignment allows.

memmove() is used to copy from an overlapping source and destination area (say moving an array's contents around within itself or something similiar - hence the move mnemonic). It uses strategies (such as possibly copying data starting at the back instead of the front) to protect against problems caused by overlapping regions. It also may be slightly less efficient as there usually isn't much hardware help copying data from back to front.

bcopy() and its relatives (bzero, and a few others) is a byte copy function I've seen now and then in embedded land. Usually, it copies data one byte at a time from source to destination to prevent misaligned memory address issues, though any good memcpy will handle this so its use is quite often suspect.

Good luck!


You should never use strncpy (unless you are dealing with that rare specific situation it was introduced for). The function is not intended to be used with zero-terminated C-strings. The name given to that function is just a historical blunder, and happens to be the main source of the confusion for the people who attempt to use it. strncpy is a function introduced to support so-called "fixed width" strings, not zero-terminated strings. Using strncpy with zero-terminated strings is bad programming practice, even though you can whip it into some resemblance of "working" for that purpose.

A function for limited length "safe" string copying does not exist in C library, however some implementations provide it under the name strlcpy, which already became a de-facto standard name for this function. If your implementation does not provide strlcpy, implement it yourself.

Also, it is true that in many cases you can replace str... function with mem... functions, i.e. when you know the exact number of characters to copy.


strcpy (and other str* methods) stop when they encounter a NULL (0) byte. memcpy and related functions to NOT stop when they encounter a NULL byte.

If you have binary data, you must use memcpy. In your example, you are copying binary data, not string data.

strncpy is a special case where it will stop copying at a NULL byte, but still continue to pad the output with NULLs up to the specified length.


If you don't need the buffer-filling behavior of strncpy but want the safety of not overflowing the buffer, consider strlcpy

From wikipedia:

strlcpy offers two features that are designed to help software developers avoid problems. The function takes the size of the destination as a parameter, avoiding buffer overflows if the size parameter is correct. If this size is greater than zero, a nul byte is always written to the destination, so the resulting string is always nul-terminated (even if the source string was truncated to fit).


Use strncpy() only if you know there's enough space for the string - because it does not guarantee null termination, and is over-enthusiastic if the destination is way shorter than the source string (because it null pads the string to full length). And if you know the length, you can use memmove()...

If you know the lengths of the strings, memmove() is a sensible choice - and nominally faster than strncpy() because it does not have to check for nulls as it goes; it just copies the relevant number of bytes. (I pretend memcpy() doesn't exist as it can fail if the source and destination areas of memory overlap, whereas memmove() will get it right regardless.)

Think of bcopy() as an archaic variant of the mem*() functions.


If you're looking for a safe/fast way to copy, I've been happy with the following technique:

memcpy( dest, src, sizeof (dest));
dest[sizeof(dest) - 1] = '\0';       // ensure null termination

Less efficient, but also works to limit the bytes written and null-terminate the string:

sprintf( dest, sizeof (dest), "%s", src);

Also returns the number of bytes it would have written, so you can tell if truncation took place.

0

精彩评论

暂无评论...
验证码 换一张
取 消