strcmp有什么问题?

Dav*_*ary 9 c string deprecated strcmp

在阅读字符串中的问题并将其与C进行比较时,不止一个人不鼓励使用strcmp(),说像

我也强烈建议你现在习惯使用strncmp(),以避免很多问题.

或(为什么我的字符串比较失败?)

确保你使用strncmp而不是strcmp.strcmp非常不安全.

他们提到了什么问题?

之所以scanf()用绳子符和gets()强烈劝阻,是因为他们几乎不可避免地导致缓冲区溢出漏洞.但是,用缓冲区溢出是不可能的strcmp(),对吧?

"缓冲区溢出或缓冲区溢出是一种异常现象,程序在将数据写入缓冲区时会超出缓冲区的边界并覆盖相邻的内存."

( - 维基百科:缓冲区溢出).

由于strcmp()函数永远不会写入任何缓冲区,strcmp()函数不会导致缓冲区溢出,对吧?

人们不鼓励使用strcmp()和推荐的原因是什么strncmp()?

Jon*_*art 17

虽然strncmp可以防止你超越缓冲区,但它的主要目的不是为了安全.相反,它存在于人们想要仅比较(恰当可能是NUL终止的)字符串的前N个字符的情况.

从手册页:

该strcmp()函数比较两个字符串s1和s2.如果s1找到小于,等于或大于零的整数,则返回小于,匹配或大于的整数s2.

该strncmp()函数类似,只是它比较了唯一的第一个(最多)n字节s1和s2.

请注意,strncmp在这种情况下不能用简单替换memcmp,因为你仍然需要利用其停止在NUL上的行为,以防其中一个字符串短于n.

如果strcmp导致缓冲区溢出,则两件事之一成立:

  1. 您的数据预计不会被NUL终止,您应该使用它memcmp.
  2. 你的数据被预期为NULL结尾的,但你已经搞砸了,当你填入缓冲区,通过某种方式不NUL终止它.

请注意,超过缓冲区末尾的读取仍被视为缓冲区溢出.虽然它看起来似乎无害,但它可能与写到最后一样危险.

阅读,写作,执行......没关系.对非预期地址的任何内存引用都是未定义的行为.在最明显的情况下,您尝试访问未映射到进程的地址空间的页面,从而导致页面错误,以及随后的SIGSEGV.在最坏的情况下,有时会遇到\ 0字节,但有时会遇到其他缓冲区,导致程序行为不稳定.

  • "它存在于人们只想比较(正确NUL终止的)字符串的前N个字符的情况." 是不正确的.从C规范"strncmp函数返回一个整数...相应地作为s1指向的可能以null结尾的数组".`int strncmp(const char*s1,const char*s2,size_t n)的`s1`和`s2`都不是;`需要是C字符串.独立地,它们可以简单地是字符串,或者它们可以是`char`的数组,而不是"正确NUL终止". (2认同)

Kei*_*son 6

根据定义,字符串是"由第一个空字符终止并包括第一个空字符的连续字符序列".

其中唯一的情况下strncmp()会更安全比strcmp()当你比较两个字符数组作为字符串是,你是一定的,这两个阵列至少n字节长(传递给第三个参数strncmp()),而你不肯定的是,两个数组包含字符串(即包含'\0'空字符终止符).

在大多数情况下,您的代码(如果它是正确的)将保证任何应该包含以null结尾的字符串的数组实际上都包含以null结尾的字符串.

添加n的strncmp()不是一个魔术棒,使不安全的代码安全.它不会防止空指针,未初始化的指针,未初始化的数组,不正确的值n,或只是传递不正确的数据.无论哪种功能,你都可以用脚射击自己.

如果您正在尝试调用strcmp或strncmp使用您认为包含空终止字符串但实际上没有的数组,那么您的代码已经存在错误.使用strncmp()可能会帮助您避免该错误的直接症状,但它不会修复它.