Small question about runtime error in C++


  • 0
    W
        class Solution {
        public:
    	bool isMatch(string s, string p) {
    		return isMatch( s, p);
    	}
    
    	bool isMatch(char * s, char* p) {
    		if (*p == (char)0) return *s == '\0';
    
    		if (*(p + 1) != '*') {
    			if (*p == *s || (*p == '.' && *s != '\0')){
    				return isMatch(s+1, p + 1);
    			}
    			else return 0;
    		}
    		else{
    			while (*p == *s || (*p == '.' && *s != '\0')){
    				if (isMatch(s, p + 2)) return 1;
    				s++;
    			}
    			return isMatch(s, p + 2);
    		}
    
    
    	}
    
    
    };
    

    this one shows a run time error, but it works fine with visual studio.
    Then I change line 4 into return isMatch( &(s[0]), &(p[0])); it works.
    May I ask why? I thought return isMatch( &(s[0]), &(p[0])); should be equal to return isMatch( s, p);
    Although test is passed, I really would like to know why, thank you a lot ahead.


  • 0
    F

    Because you overloaded function isMatch(), your two versions are:

    isMatch(string, string) and
    isMatch(char *, char *)

    C++ does static binding which means that your function call will be known to the compiler during compilation instead of runtime. In your case, compiler will be a little bit confused about your overloading, since you passed two strings to isMatch(), and both version of isMatch() is capable of accepting these two arguments (C++ string library defines type inference from string to char *, that's why compiler allows you to pass string while argument is specified as char *). So, how does compiler know which isMatch should call when you perform a "recursive" call of isMatch() inside isMatch()?

    C++ language definition tells us it chooses the most direct one, requiring minimum number of type cast (from string to string does not need case, while from string to char * needs one cast). In your case, the problem is very clear: You called isMatch() inside isMatch(), and you passed string as arguments. This makes compiler call the string version of isMatch() function instead of your overloaded, char * version.

    Therefore, in your previous code, you are actually doing recursion, and this will definitely blow up the stack and throw an error. In your corrected code, you changed from string to &string[0], which is essentially different, because string[0] will call operator overloading defined for class string, which returns the first character of the underlying c string, and then you get its address using & operator, which happens to be the right type of argument to use for compiler to call your char * version of overloaded function.


Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.