我写了一个类似这样的函数:
bool IsSameString(char* p1, char* p2)
{
return 0 == strcmp(p1, p2);
}
问题在于有时候会不小心传递非字符串参数(这意味着p1
或p2
没有以null字符结尾)。然后,strcmp继续比较直到达到不可访问的内存并崩溃。
是否有一个安全版本的strcmp?或者我可以以安全的方式判断p1
(和p2
)是否为字符串?没有(标准)方法可以判断 char *
是否实际指向有效的内存。
在您的情况下,最好使用 std::string
代替所有字符串中的 char *
,以及重载 ==
运算符。如果这样做,编译器会强制执行类型安全。
编辑:根据下面的评论,如果您发现自己处于这样一种情况:有时将可能是有效字符串的 char *
传递给期望以空字符结尾的字符串的函数,那么您的方法基本上是错误的,可以参考@janm的回答。
bool
,因此假设是C++也是合理的。此外,这个答案已经超过3年了。 - Wernseystd::string xxx=(char *)whatever;
- OP 应该使用 std::string
来处理 所有 字符串。这样他就可以利用编译器提供的功能,比如类型安全和重载的 ==
运算符(这将消除他对 安全 strcmp
函数的需求)。但你说得对,如果 OP 的 char*
有时指向字符串,有时指向无效数据,那么在更基本的层面上就有问题了。 - Wernsey在某些情况下,std::strncmp
可以解决你的问题:
int strncmp ( const char * str1, const char * str2, size_t num );
该函数将C字符串str1的前num个字符与C字符串str2进行比较。
此外,看一下美国国土安全部国家网络安全局在这个问题上的建议:
确保在传递给strcmp函数之前,字符串已经以null结尾。可以通过在缓冲区的最后一个分配的字节中始终放置\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 */ }
如果你将非空结尾的字符串传递给strcmp()函数,那么你已经失败了。事实上,你有一个不应该缺少空结尾的字符串(但实际上确实缺少了),这表明你的代码存在更深层次的问题。你不能更改strcmp()函数以安全地解决这个问题。
你应该编写代码,使其不可能发生这种情况。首先使用string类。在你将数据引入代码的边界处,你需要确保处理异常情况;如果你获取太多的数据,你需要采取正确的措施。这不涉及运行超出缓冲区的末尾。如果必须将数据输入到C样式的缓冲区中,请使用指定缓冲区长度并检测和处理缓冲区在某一点上不够大的情况的函数。
没有可以移植的解决方法。约定规定,字符串本身属于正确分配的内存块,并且有一个额外的字符包含空字符。如果遵循这个约定,一切都好,否则会发生未定义的行为。
如果您知道要比较的字符串的长度,可以使用strncmp()
,但如果传递给您的代码的字符串实际上比您要比较的字符串短,则无济于事。
您可以使用strncmp,但如果可能的话,请使用std :: string来避免许多问题 :)
您可以使用strncmp函数来限制要比较的字符数量上限。
strcmp(s1, s2)
不会在 s1
中查找超过 s2
字符数的内容,同时,你必须比较它们中最短的字符串的完整长度.. 所以 strncmp
无法帮助解决问题。 - u0b34a0f6ae关于这个问题并没有最好的答案,因为你不能验证 char* 是否是字符串。唯一的解决方案是创建一个类型并将其用于字符串,例如 str::string,或者自己创建一个轻量级的字符串类型。
struct MyString
{
MyString() : str(0), len(0) {}
MyString( char* x ) { len = strlen(x); str = strdup(x); }
⁓MyString() { if(str) free(str); }
char* str;
size_t len;
};
bool IsSameString(MyString& p1, MyString& p2)
{
return 0 == strcmp(p1.str, p2.str);
}
MyString str1("test");
MyString str2("test");
if( IsSameString( str1, str2 ) {}
std::string
可以做到你的类所能做的一切,而且没有额外的成本。轻量级并不等于功能较少。 - GManNickG您没有说明使用的平台。Windows 平台有以下函数:
如果您使用的是 Windows 平台,IsBadStringPtr
可能是您要找的函数。
#include
我希望... - Ephemera