14

我做了一个这样的函数:

bool IsSameString(char* p1, char* p2) 
{
     return 0 == strcmp(p1, p2);
}

问题是,有时错误地传递了不是字符串的参数(这意味着p1orp2不以空字符终止)。然后,strcmp继续比较,直到它到达不可访问的内存并崩溃。有安全的版本strcmp吗?或者我可以以安全的方式判断p1(and p2) 是否是字符串?

4

8 回答 8

21

不,没有(标准)方法可以判断 a 是否char *实际指向有效内存。

在您的情况下,最好对所有字符串使用std::string而不是char *s 以及重载==运算符。如果您这样做,编译器将强制执行类型安全。

编辑:根据下面的评论,如果您发现自己有时将char *可能是或可能不是有效字符串的 s 传递给期望以空结尾的字符串的函数,那么您的方法从根本上是错误的,所以基本上@janm 的回答如下.

于 2009-10-26T09:06:46.513 回答
18

在某些情况下std::strncmp可以解决您的问题:

int strncmp ( const char * str1, const char * str2, size_t num ); 

它将 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 */ }
于 2009-10-26T09:05:11.223 回答
14

如果您将字符串传递给 strcmp() 不是空终止的,那么您已经丢失了。您的字符串不是以空结尾(但应该是)的事实表明您的代码中存在更深层次的问题。您无法更改 strcmp() 以安全地处理此问题。

您应该编写代码,这样就永远不会发生。从使用字符串类开始。在将数据放入代码的边界处,您需要确保处理异常情况;如果您获得太多数据,您需要做正确的事。这不涉及耗尽​​缓冲区的末端。如果您必须对 C 风格的缓冲区执行 I/O,请使用指定缓冲区长度的函数,并检测和处理缓冲区在该点不够大的情况。

于 2009-10-26T11:19:39.797 回答
7

便携式无法治愈。约定规定有一个额外的字符包含一个空字符,该字符属于与字符串本身相同的正确分配的内存块。要么遵循此约定,要么发生一切正常或未定义的行为。

如果您知道要比较的字符串的长度,则可以使用strncmp(),但如果传递给您的代码的字符串实际上比您比较的字符串短,他将无济于事。

于 2009-10-26T09:04:38.773 回答
3

你可以使用strncmp,但如果可能的话使用std::string来避免很多问题:)

于 2009-10-26T09:07:02.250 回答
1

您可以使用strncmp函数对要比较的字符数设置上限。

于 2009-10-26T09:06:22.763 回答
-1

对此没有最佳答案,因为您无法验证 char* 是字符串。唯一的解决方案是创建一个类型并将其用于字符串,例如 str::string 或者如果您想要更轻的东西,请创建您自己的类型。IE

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 ) {}
于 2009-10-26T11:08:12.590 回答
-2

你不写,你用的是什么平台。Windows 具有以下功能:

IsBadStringPtr如果您使用的是 Windows,可能是您正在寻找的东西。

于 2009-10-26T10:57:21.023 回答