Question

I made a function like this:

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

The problem is that sometimes, by mistake, arguments are passed which are not strings (meaning that p1 or p2 is not terminated with a null character). Then, strcmp continues comparing until it reaches non-accessible memory and crashes. Is there a safe version of strcmp? Or can I tell whether p1 (and p2) is a string or not in a safe manner?

Was it helpful?

Solution

No, there's no (standard) way to tell whether a char * actually points to valid memory.

In your situation, it is better to use std::string rather than char *s for all your strings, along with the overloaded == operator. If you do this, the compiler would enforce type safety.

EDIT: As per the comments below if you find yourself in a situation where you sometimes pass char *s that may or may not be valid strings to functions that expect null-terminated strings then something is fundamentally wrong with your approach, so basically @janm's answer below.

OTHER TIPS

In some cases std::strncmp can solve your problem:

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

It compares up to num characters of the C string str1 to those of the C string str2.


Also, take a look, what the US DHS National Cyber Security Division recommends on this matter:

Ensure that strings are null terminated before passing into strcmp. This can be enforced by always placing a \0 in the last allocated byte of the buffer.

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 */ }

If you are passing strings to strcmp() that are not null terminated you have already lost. The fact that you have a string that is not null terminated (but should be) indicates that you have deeper issues in your code. You cannot change strcmp() to safely deal with this problem.

You should be writing your code so that can never happen. Start by using the string class. At the boundaries where you take data into your code you need to make sure you deal with the exceptional cases; if you get too much data you need to Do The Right Thing. That does not involve running off the end of your buffer. If you must perform I/O into a C style buffer, use functions where you specify the length of the buffer and detect and deal with cases where the buffer is not large enough at that point.

There's no cure for this that is portable. The convention states that there's an extra character holding a null character that belongs to the same correctly allocated block of memory as the string itself. Either this convention is followed and everything's fine or undefined behaviour occurs.

If you know the length of the string you compare against you can use strncmp() but his will not help if the string passed to your code is actually shorter than the string you compare against.

you can use strncmp, But if possible use std::string to avoid many problems :)

You can put an upper limit on the number of characters to be compared using the strncmp function.

There is no best answer to this as you can't verify the char* is a string. The only solution is to create a type and use it for string for example str::string or create your own if you want something lighter. 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 ) {}

You dont write, what platform you are using. Windows has the following functions:

IsBadStringPtr might be what you are looking for, if you are using windows.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top