strlcpy:源和目标指向同一个对象

strlcpy: source and destination points to the same object

我才刚刚开始理解strlcpy

size_t strlcpy(char *destination, const char *source, size_t size);

我假设的问题是:如果目标和源指向同一个对象怎么办?

示例:

char destination[100];

const char*source = "text";

destination = source;

strlcpy(destination, source, sizeof(destination))

后端发生了什么?

strlcpy 知道源和目标共享同一个指针吗?

它是否盲目复制并浪费 cpu 周期 - 复制相同的字节?

strlcpy 将复制缓冲区长度并确保字符串以 0' 结尾。它不会检查您的 dest 和 src 是否相同,您需要验证指针是否指向相同的地址。如果不是,它只会重写数据并确保 dest 的最后一个字节是 0。

What if the destination and source point to the same object?

strlcpy() 不是 C 标准库的一部分。其精确功能可能因编译器而异。查看特定 compiler/library 的文档以获得最佳答案。

作为 BSD 系统的一部分,strlcpy(3) - Linux man page,我没有发现任何不允许重叠的内容。


从 C99 开始,关键字 restrict 有助于回答 "What if the destination and source point to the same object?" 部分。

如果签名如下所示,那么使用 destination, source 引用重叠数据是 未定义的行为 。什么事都有可能发生。

size_t strlcpy(char * restrict destination, const char * restrict source, size_t size);

如果签名如下并且编译器符合 C99 或更高版本,则使用可能重叠的 destination, source 是已定义的行为。

如果签名如下并且编译器不符合 C99 或更高版本,那么使用可能重叠的 destination, source 可能会 未定义的行为 除非文档解决了这个问题案例.

size_t strlcpy(char * destination, const char *source, size_t size);

由于 strlcpy 不是由 ISO C 标准或我所知道的任何其他 "official" 标准定义的,因此这个问题不一定有规范的答案。

最接近此功能官方规范的可能是由 OpenBSD 的创建者 Theo de Raadt 合着的 OpenBSD man page, since the function was introduced in a paper。 (这篇论文的第一作者是 Todd C. Miller。)这个手册页说:

If the src and dst strings overlap, the behavior is undefined.

特别是,您可以在 the source 中看到,如果您要执行该特定实施

char buf[20] = "hello world";
char *dest = buf+2;
strlcpy(dest, buf, 18);

然后 dest 最终会指向字符串 "heheheheheheheheh" 而不是您可能想要的 "hello world"

由于至少有一个突出的实现属于这种情况,因此建议您永远不要在可能重叠的字符串上调用该函数,因为您的代码至少可移植性较差。