memset 和 _strnset 的区别
Posted
技术标签:
【中文标题】memset 和 _strnset 的区别【英文标题】:Difference between memset and _strnset 【发布时间】:2015-09-18 21:46:44 【问题描述】:我无法弄清楚以下两个实现之间到底有什么区别:
char str[20] = "Hello World";
_strnset(str, '*', 5);
和
char str[20] = "Hello World";
memset(str, '*', 5);
它们都产生以下结果:
输出:***** 世界!
他们之间有偏好吗?
【问题讨论】:
请注意,strnset
不是标准的 C 函数。
每个人都知道 memset() 的作用。当它以 _ 下划线开头时,您会祈祷并希望它仍然像 20 年前一样工作,当您移植时不需要花费一个小时删除这些下划线并且不会破坏您的堆栈。是的,您有偏好。
memset(void *p,...)
不需要 p
指向字符串。 _strnset(char *str, ...)
指定 str
指向一个字符串。 Ref
【参考方案1】:
_strnset
知道它正在处理字符串,因此会尊重空终止符。 memset
没有,所以不会。
至于偏好,
memset
符合 C 和 C++ 标准,_strnset
两者都不符合。
如果可用,_strnset
可以在您编写错误代码时避免缓冲区溢出。
如果您知道您将继续使用 Windows,请使用 _strnset
。否则memset
。
【讨论】:
对。文档中的这句话证明了:“如果 count 大于 str 的长度,则使用 str 的长度而不是 count。” 我可以举一个空终止符被尊重与否的例子吗?"Hello World"
有 11 个字符,加上 '\0'
的 1 个字节。所以,比较 _strnset(str, '*', 15)
和 memset(str, '*', 15)
。
@pistachiobk 就像 Max 演示的那样,如果您传递的 n
大于缓冲区大小,_strnset
能够检测到这一点,因为它将在空终止符处停止。 memset
将溢出缓冲区,这是一个潜在的严重错误。
Microsoft 宁愿您使用_strnset_s
,这是一种“安全”变体,可以进行更多检查。如果你打算继续使用 Windows,我会使用其中之一,主要是因为最终你会想要转移到 Unicode 字符串,而 memset
将无法处理这些。以上是关于memset 和 _strnset 的区别的主要内容,如果未能解决你的问题,请参考以下文章