2

我刚刚开始了解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周期-复制相同的字节?

4

3 回答 3

1

如果目标和源指向同一个对象怎么办?

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

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


从 C99 开始,关键字restrict有助于回答“如果目标和源指向同一个对象怎么办?” 部分。

如果签名如下,则使用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);
于 2020-03-06T22:05:57.083 回答
0

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

于 2020-03-06T19:12:44.257 回答
0

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

与该函数的官方规范最接近的可能是OpenBSD 手册页,因为该函数是在OpenBSD 的创建者 Theo de Raadt 合着的一篇论文中介绍的。(该论文的第一作者是 Todd C. Miller。)这个手册页说:

如果 src 和 dst 字符串重叠,则行为未定义。

特别是,您可以在源代码中看到使用该特定实现,如果您要这样做

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

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

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

于 2020-03-06T22:18:42.963 回答