Jac*_*ack 3 c optimization performance
可能重复:
为什么要使用strncpy而不是strcpy?
我正在读一本关于计算机/加密等的书.通常作者使用的东西,strncpy(dest, src, strlen(src));而不是strcpy(dest, src);它对我来说没什么意义..好吧,我是一个专业的程序员.
问题是:它真的有一个真正的区别吗?真正的应用使用这样的东西?
Die*_*Epp 13
作者几乎肯定会滥用这些strn*功能.不幸的是,几乎没有充分的理由使用strn*函数,因为它们实际上并不是你想要的.
我们来看看strcpy和strncpy:
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t n);
Run Code Online (Sandbox Code Playgroud)
该strcpy函数复制src到dest,包括尾随\0.它很少有用:
除非您知道源字符串适合目标缓冲区,否则会出现缓冲区溢出.缓冲区溢出是安全隐患,它们可能会导致程序崩溃,并导致程序运行不正常.
如果您确实知道源字符串和目标缓冲区的大小,那么您也可以使用memcpy.
相比之下,strncpy复制最多的n字节为src进入dest,然后填补其余部分\0.它很少有用:
除非您知道源字符串小于目标缓冲区,否则您无法确定生成的缓冲区是否为空终止.如果您认为结果是以空值终止的,则可能会导致程序中其他位置出错.
如果您确实知道源字符串较小,那么您也可以使用memcpy.
您可以在调用后终止字符串strncpy,但是您确定要静默截断结果吗?我想大部分时间,你宁愿有错误信息.
这个strcpy功能偶尔会很方便,但它主要是一个人们不太关心验证输入的时代的遗物.提供一个对程序来说太大的字符串会使它崩溃,并且建议是"不要那样做".
strncpy当您想要在固定大小的字段中传输数据时,该功能非常有用,并且您不希望在字段的其余部分中放置垃圾.这主要是人们使用固定大小字段的时代遗留物.
所以,你很少会看到strcat或者strncpy在现代C软件.
但是,您的示例结合了两个世界中最糟糕的情况.我们来看看这段源代码:
strncpy(dest, src, strlen(src));
Run Code Online (Sandbox Code Playgroud)
此副本src到dest,没有一个\0终结者和没有边界检查.它结合了strcpy(无边界检查)最糟糕的方面strncpy(没有终结者).如果您看到这样的代码,请逃跑.
好的C代码通常使用一些选项来处理字符串:
使用固定缓冲区snprintf,只要你不介意固定缓冲区.
使用有界字符串函数像strlcpy和strlcat.这些是BSD扩展.
使用跟踪字符串长度的自定义字符串点,并使用memcpy和编写自己的函数malloc.