memccpy (memccpy (d, s1, '', SIZE_MAX) - 1, s2, '', SIZE_MAX);为了避免缓冲区溢出的风险,需要为每个调用确定适当的大小限制并作为参数提供 。因此,像在snprintf(d, dsize, "%s%s", s1, s2)函数中那样限制目标大小的连接调用,可以像下面这样计算目标大小:char *p = memccpy (d, s1, '', dsize);dsize -= (p - d - 1);memccpy (p - 1, s2, '', dsize);7.选择一个解决方案如果字符串函数返回指向最后一个存储字符或它的后面一位的指针,而不是返回其第一个参数的值,则上面讨论的效率问题可以得到解决 。然而,在现有函数使用了接近半个世纪后,对其进行更改是不太可行的 。尽管解决现有C标准字符串函数的问题是不可行的,但是可以通过添加一个或多个不受相同限制的函数来在新代码中缓解这个问题 。由于C标准的章程正在对现有的实践进行编纂整理,所以C语言标准化委员有义不容辞的责任调查这种功能是否已经存在于流行的实现中,如果已经存在,则应该考虑采纳它们 。如上文提到的这几种解决方案 。
在上面提到的解决方案中,memccpy函数是最通用和最高效的,它由ISO 标准支持 。即使在POSIX标准实现之外,它的应用范围最广,争议最小 。
相比之下,stpcpy和stpncpy函数的通用性较差,stpncpy函数会产生不必要的开销,因此无法达到既定的目标 。这些函数在C2X中仍然值得采用,以提高移植性 。详情请参阅N2352–将stpcpy和stpncpy添加到C2X中的提案 。
OpenBSD的strlcpy和strlcat函数虽然是最优的,但是它们的通用性较差,支持范围也较低,而且没有得到ISO标准的指定 。
memccpy函数不仅存在于Unix实现的子集中,它还由另一个名为ISO/IEC 9945的ISO标准指定 。ISO/IEC 9945还有另外一个名字,也即大家熟知的IEEE Std 1003.1, 2017版,或者简言之- POSIX: memccpy,在那里它是作为XSI扩展提供给C的 。这个函数可以追溯到System V接口定义第1版(SVID1),最初于1985年发布 。
memccpy甚至可以用于UNIX和POSIX以外的实现,例如:
- Android/ target=_blank class=infotextkey>安卓系统中的memccpy函数,
- 苹果mac OS X中的memccpy函数,
- BlackBerry Native SDK 的memccpy函数,
- Compaq Run-Time Library for VAX中的memccpy函数,
- 微软Visual Studio C Runtime Library中的 memccpy 函数,
- IBM z/OS 中的memccpy函数.
void* memccpy (void* restrict dst, const void* restrict src, int c, size_t n){void *pc = memchr (src, c, n);void *ret;if (pc){n = (char*)pc - (char*)src + 1;ret = (char*)dst + n;}elseret = 0;memcpy (dst, src, n);return ret;}这个函数的一个更优化的实现可能如下 。 void* memccpy (void* restrict dst, const void* restrict src, int c, size_t n){const char *s = src;for (char *ret = dst; n; ++ret, ++s, --n){*ret = *s;if ((unsigned char)*ret == (unsigned char)c)return ret + 1;}return 0;}借助于memccpy的性能优化,编译器将能够把对snprintf (d, dsize, "%s", s)函数的简单调用转换为对memccpy(d, s, '', dsize)的最佳有效调用 。通过以代码大小换取速度,激进的优化器甚至可以将符合下列条件的snprintf函数调用(其格式字符串由多个%s指令组成,这些指令中间穿插有普通字符,如%s/%s)转换成一系列的此类memccpy函数调用:如下所示char *p = memccpy (d, s1, '', dsize);if (p){--p;p = memccpy (p, "/", '', dsize - (p - d));if (p){--p;p = memccpy (p, s2, '', dsize - (p - d));}}if (!p)d[dsize - 1] = '';8.2019年4月WG14会议后的更新将memccpy函数和本文讨论的其他标准函数(除了strlcpy和strlcat),以及另外两个标准函数纳入下一个C编程语言修订版的提议于2019年4月提交给了C语言标准化委员会(见 3, 4, 5和 6) 。委员会最终决定采纳memccpy函数,但否决了其余提案 。
推荐阅读
- ”什么是内网穿透“详解
- 「C语言」常用算法
- 现在开淘宝网店是不是一定要交保证金 开淘宝店必须交保证金吗
- 总结Java中return语句的用法
- Mac平台上实现视频采集
- CentOS 8 安装图解
- 白鹿茶韵词语茶香与茶友起体验传统文化的魅力
- 中欧国际茶座交易中心在新疆阿拉山口开设
- 虾球烩豆腐
- 关于茶或促进糖尿病伤口愈合的研究表明茶多酚在其中发挥作用
