strlcat(): dst 总是 NUL_terminated 吗?什么是“大小”和返回值?

vmo*_*eco 4 c

我必须从标准 C 库中实现我自己版本的 strlcat() 函数。

size_t     strlcat(char * restrict dst, const char * restrict src, size_t size);
Run Code Online (Sandbox Code Playgroud)

我有两个关于它如何工作的问题:

它是否dst在每种情况下都以NUL_terminates 结尾?

在我的男人中,我有以下几点:

strlcat() 获取缓冲区的完整大小(不仅仅是长度)并保证以 NUL 终止结果(只要大小大于 0,或者在 strlcat() 的情况下,只要至少是dst 中有 1 个字节可用)。

和 :

strlcat() 函数将 NUL 终止的字符串 src 附加到 dst 的末尾。它将最多附加 size - strlen(dst) - 1 个字节,NUL 终止结果。

但是也 :

但是请注意,如果 strlcat() 在没有找到 NUL 的情况下遍历 size 个字符,则字符串的长度被认为是 size 并且目标字符串不会以 NUL 结尾(因为 NUL 没有空间)。

那么,我应该在每种情况下 NUL_terminate dst 吗?一方面,它表示存在dst字符串不是 NUL_terminated 的情况。另一方面,该男子说strlcat()保证dst将是 NUL_terminated,并且非 NUL_terminated 字符串不会非常不安全吗?

有人可以给我一个例子,这种情况会发生吗?

返回值代表什么,为什么会出现这种行为?

以下是我通过一些测试得到的结果:

Before :                || After :
dst   | src   | size    || dst      | return
------------------------||--------------------
dst\0 | src\0 | 0       || dst\0    | 3
dst\0 | src\0 | 1       || dst\0    | 4
dst\0 | src\0 | 2       || dst\0    | 5
dst\0 | src\0 | 3       || dst\0    | 6
dst\0 | src\0 | 4       || dst\0    | 6
dst\0 | src\0 | 5       || dsts\0   | 6
dst\0 | src\0 | 6       || dstsr\0  | 6
dst\0 | src\0 | 7       || dstsrc\0 | 6
dst\0 | src\0 | 8       || dstsrc\0 | 6
Run Code Online (Sandbox Code Playgroud)

再次来自男人:

[strlcat() 函数] 返回 [它试图] 创建的字符串的总长度。对于 strlcat() 这意味着 dst 的初始长度加上 src 的长度。

dst's 和src's 的大小在我的测试中是恒定的(3 和 3)。那么为什么会出现返回值与 6 不同的情况呢?

不是(len(dst) + min(size, len(src))吗?

大小代表什么?

strlcat() 函数将 NUL 终止的字符串 src 附加到 dst 的末尾。它将最多附加 size - strlen(dst) - 1 个字节,NUL 终止结果。

所以大小应该是最后dst允许的长度(包括'\0'字符)?那正确吗?

ric*_*ici 5

1. strlcat 总是空终止dst吗?

dst将被strlcatifstrlcat修改为空终止dstdst如果dst已经被完全占用,strlcat 不会修改。dst如果NUL在的第一个size - 1字节中没有找到dst(或者如果size是 0),则认为已被完全占用。

所以有两种情况dst不会被空终止strlcat。一种是dst完全以空字符结尾的size - 1字节字符串,在这种情况下,它不会被修改并继续以空字符结尾。第二种情况是dst最初没有以空值终止,在这种情况下,在调用strlcat.

2. 原始目的字符串的长度是如何测量的?

size预期为包含 的内存区域的大小dst,因此dst[size]假定为无效内存引用。因此,如果dst开始了作为一个有效的(并且因此空终止)串,其长度会比严格少size并且strlcat将使用strlen(dst)作为其长度。如果dst无效,则假定其大小size用于返回值。在这种情况下,dst将不会被修改。看上面。

  • @vmonteco:我认为从我的回答中可以看出这一点。它是“min(size, strlen(dst)) + strlen(src)”,它只查看最大 size 个字符来计算左侧表达式。 (2认同)