我必须从标准C库中实现我自己的strlcat((函数版本。
size_t strlcat(char * restrict dst, const char * restrict src, size_t size);
我有两个关于它如何工作的问题:
它是否在每种情况下都NUL_terminates dst
?
在我的男人身上,我有以下几点:
strlcat(( 获取缓冲区的完整大小(而不仅仅是长度(和 保证 NUL 终止结果(只要大小大于 0,或者在 strlcat(( 的情况下,只要 DST 中至少有一个字节可用(。
和:
strlcat(( 函数将 NUL 终止的字符串 src 附加到 夏令时结束。 它将以最大大小附加 - strlen(dst( - 1 字节, NUL 终止结果。
而且 :
但是请注意,如果 strlcat(( 遍历大小字符,则没有 找到一个 NUL,字符串的长度被认为是大小和 目标字符串不会以 NUL 结尾(因为没有 NUL 的空间(。
那么,我应该在每种情况下都NUL_terminate dst 吗?一方面,它说有一种情况是dst
字符串不NUL_terminated。另一方面,男人说strlcat()
保证dst
会NUL_terminated,一个非NUL_terminated的字符串不是很不安全吗?
有人可以给我举个例子,这个案子会发生在哪里?
返回值表示什么,为什么会出现这种行为?
以下是我通过一些测试得到的结果:
Before : || After :
dst | src | size || dst | return
------------------------||--------------------
dst | src | 0 || dst | 3
dst | src | 1 || dst | 4
dst | src | 2 || dst | 5
dst | src | 3 || dst | 6
dst | src | 4 || dst | 6
dst | src | 5 || dsts | 6
dst | src | 6 || dstsr | 6
dst | src | 7 || dstsrc | 6
dst | src | 8 || dstsrc | 6
再次从男人那里:
[strlcat(( 函数] 返回字符串的总长度 [it 尝试]创建。对于 strlcat((,这意味着 dst 的初始长度 加上 SRC 的长度。
在我的测试中,dst
和 src
的大小是恒定的(3 和 3(。那么为什么会出现返回值与 6 不同的情况呢?
不是很(len(dst) + min(size, len(src))
吗?
尺寸代表什么?
strlcat(( 函数将 NUL 终止的字符串 src 附加到 夏令时结束。 它将以最大大小附加 - strlen(dst( - 1 字节, NUL 终止结果。
所以大小应该是长度(包括"\0"字符(,dst
允许在最后?是吗?
1. strlcat 总是空终止dst
吗?
如果dst
修改dst
,strlcat
将以 null 结尾strlcat
。如果 Strlcat 已满dst
则不会修改dst
。 如果在dst
的前 size - 1
个字节中找不到NUL
(或者如果size
为 0(,则认为dst
已满。
因此,在两种情况下,dst
不会被 strlcat
终止 null。一个是dst
是一个正好 size - 1
个字节的以 null 结尾的字符串,在这种情况下,它不会被修改并继续以 null 结尾。第二种情况是dst
最初没有以 null 终止,在这种情况下,它在调用 strlcat
后仍将未终止。
2. 如何测量原始目标字符串的长度?
size
应该是包含 dst
的内存区域的大小,因此dst[size]
被假定为无效的内存引用。因此,如果 dst
以有效(因此以 null 结尾(字符串开头,则其长度将严格小于 size
,并且strlcat
将使用 strlen(dst)
作为其长度。如果 dst
无效,则假定其大小size
返回值。在这种情况下,dst
不会被修改。见上文。
我认为返回的值strnlen(dst) + strlen(src)
不是min(size, strlen(dst)) + strlen(src)
。这是因为当dst
未以 null 终止时,strlen(dst)
将访问无效内存。