我做了一个这样的函数:

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

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

有帮助吗?

解决方案

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

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

编辑:根据以下评论,如果您发现自己处于有时会传递 char * 的情况,这些字符可能是也可能不是有效的字符串以null结尾的字符串然后基本上是你的方法的根本错误 @ janm的答案如下。

其他提示

在某些情况下, 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 */ }

如果您将字符串传递给非空终止的strcmp(),那么您已经丢失了。您有一个非空终止字符串(但应该是)的事实表明您的代码中存在更深层次的问题。你不能改变strcmp()来安全地处理这个问题。

您应该编写代码,以免永远发生。首先使用字符串类。在将数据导入代码的边界处,您需要确保处理特殊情况;如果你得到太多的数据,你需要做正确的事。这不涉及逃避缓冲区的结束。如果必须在C样式缓冲区中执行I / O,请使用指定缓冲区长度的函数,并检测并处理缓冲区在此时不够大的情况。

便携式无法解决这个问题。约定规定,有一个额外的字符,其中包含一个空字符,该字符属于与字符串本身相同的正确分配的内存块。遵循此约定并且发生一切正常或未定义的行为。

如果您知道与之比较的字符串的长度,可以使用 strncmp()但如果传递给您的代码的字符串实际上比您比较的字符串短,则无效。

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

没有最佳答案,因为您无法验证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 ) {}

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top