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

strlcpy:源和目标指向同一对象,c,strlcpy,C,Strlcpy,我刚刚开始理解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)) 后端发生了什么 st

我刚刚开始理解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

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

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

作为BSD系统的一部分,我没有发现任何不允许重叠的地方


自C99以来,关键字
restrict
有助于回答“如果目标和源指向同一对象怎么办?”部分

如果签名如下,而不是使用
destination,那么源
引用重叠数据是未定义的行为。任何事情都有可能发生

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

如果签名如下,并且编译器符合C99或更高版本,而不是使用
目标,则定义了可能重叠的源代码


如果签名如下,并且编译器没有向C99或更高版本投诉,而不是使用
目标,则可能重叠的源代码可能是未定义的行为,除非文档解决了这种情况

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

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

与该函数的官方规范最接近的可能是,因为该函数是由OpenBSD的创建者Theo de Raadt合著的。(该论文的第一作者是托德·C·米勒。)该手册页上写道:

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

特别是,您可以通过特定的实现看到这一点,如果您要这样做的话

char buf[20] = "hello world";
char *dest = buf+2;
strlcpy(dest, buf, 18);
然后
dest
将指向字符串
“heheheheheheheh”
,而不是
“hello world”
,这可能是您想要的


因为至少有一个突出的实现是这样的,所以最好不要在可能重叠的字符串上调用该函数,因为您的代码至少不太便于移植。

有多种实现,但请看一个示例的源代码-“”。据我所知,这适用于
中的所有字符串复制函数。在我的系统手册页中:“如果src和dst字符串重叠,则行为未定义。”在文档中,行为未定义。memmove将安全地复制重叠字符串“如果签名如下且编译器符合C99或更高版本,而不是使用目标,则可能重叠的源是定义的行为。”好的,“定义”是指C语言允许您进行此类调用。但是没有人能保证当你这么做的时候,
strlcpy
会做任何合理的事情。@NateEldredge。IAC,如果
strlcpy()
适应Std C库,我希望
restrict
或显式函数定义。在此之前,谨慎的编码会假设情况更糟,而不会尝试重叠缓冲区。