我做了这样的功能:
bool IsSameString(char* p1, char* p2)
{
return 0 == strcmp(p1, p2);
}
Run Code Online (Sandbox Code Playgroud)
问题是,有时,错误地传递了不是字符串的参数(意味着p1
或p2
不以空字符终止).然后,strcmp
继续比较,直到它到达不可访问的内存并崩溃.有安全版strcmp
吗?或者我能否以安全的方式判断p1
(和p2
)是否为字符串?
Wer*_*sey 17
不,没有(标准)方法来判断char *
实际是否指向有效内存.
在您的情况下,最好使用std::string
而不是char *
s来表示所有字符串,以及重载==
运算符.如果这样做,编译器将强制类型安全.
编辑:根据下面的评论,如果你发现自己处于这样的情况,你有时将char *
s可能或不是有效的字符串传递给期望以null结尾的字符串的函数,那么你的方法基本上是错误的,所以基本上@janm的答案如下.
Igo*_*Oks 14
在某些情况下std::strncmp
可以解决您的问题:
int strncmp ( const char * str1, const char * str2, size_t num );
Run Code Online (Sandbox Code Playgroud)
它将C字符串str1的最多num个字符与C字符串str2的字符数进行比较.
另外,看看美国国土安全部国家网络安全部门就此问题推荐的内容:
确保在传入strcmp之前字符串为空终止.这可以通过始终在缓冲区的最后分配字节中放置\ 0来强制执行.
char str1[] ="something";
char str2[] = "another thing";
/* In this case we know strings are null terminated. Pretend we don't. */
str1[sizeof(str1)-1] = '\0';
str2[sizeof(str2)-1] = '\0';
/* Now the following is safe. */
if (strcmp(str1, str2)) { /* do something */ } else { /* do something else */ }
Run Code Online (Sandbox Code Playgroud)
jan*_*anm 10
如果您将字符串传递给非空终止的strcmp(),那么您已经丢失了.您有一个非空终止字符串(但应该是)的事实表明您的代码中存在更深层次的问题.你不能改变strcmp()来安全地处理这个问题.
您应该编写代码,以便永远不会发生.首先使用字符串类.在将数据导入代码的边界处,您需要确保处理特殊情况; 如果你得到太多的数据,你需要做正确的事.这不涉及逃避缓冲区的结束.如果必须将I/O执行到C样式缓冲区,请使用指定缓冲区长度的函数,并检测并处理缓冲区在该点处不够大的情况.
便携式无法解决这个问题.约定规定,有一个额外的字符,其中包含一个空字符,该字符属于与字符串本身相同的正确分配的内存块.遵循此约定并且发生一切正常或未定义的行为.
如果你知道你比较的字符串的长度你可以使用,strncmp()
但如果传递给你的代码的字符串实际上比你比较的字符串短,他将无济于事.