Why am I getting "runtime error: Segmentation fault" for random test cases?

Why am I getting "runtime error: Segmentation fault" for random test cases?

我被要求检查给定的字符串在重新排列后是否可以是回文,然后 return 如果它可以是回文则为真,如果它不能是回文则为假。

我收到运行时错误:运行 测试时出现分段错误。

这是我的代码:

bool palindromeRearranging(char * inputString) {
    
    int index;
    int count, count1 = 0;
    
    for(int i = 0, b = strlen(inputString); i < b -1 ; i++)
    {    count = 0;
        if(inputString[i] == '*')
        {
            continue;
        }else 
        {        
            for(int j = i+1; j < b ;j++)
            {           
              if(inputString[i] == inputString[j] )
                {                     
                  inputString[j] = '*';
                  count++;
                  index = i;
                }
          
            }
         inputString[index] = '*';
        }
        
        if(count %2 == 0 && count != 0)
        {
            count1++;
        }
    }
    
    for(int i = 0, b = strlen(inputString); i < b; i++)
    {
        if(inputString[i] != '*')
        {
            count1++;
        }
    }
 
    if(count1 > 1)
    {
        return false;
    }else
    {
        return true;
    }

}

这里inputString是给出的字符串。如果这两个字符相同,我尝试用 * 替换它们。然后数数。单个字符。

10 个测试用例中有 5 个通过。

例如 "abbcabb""aabb""zyyzzzzz" 等测试用例已通过。

但我收到运行时错误:"abcad""aaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbccccaaaaaaaaaaaaa" 等测试用例的分段错误。 "abca", "abdhuierf".

我希望你能帮我解决这个问题。

顺便说一下,我正在 codesignal.com 的拱廊 section/intro 下解决这个问题。 Q.18 回文重排.

"Why am I getting “runtime error: Segmentation fault” for random test cases?"

除了你的函数在逻辑上不能用于测试回文之外,由于 undefined behavior:

它会在随机情况下失败
int index;

未初始化,

这里失败,例如当它的值超过数组索引时:

inputString[index] = '*';

具有以下 运行 次消息序列:

要解决这个问题,请更改:

int index;
int count, count1 = 0;

对此:

int index = 0;
int count = 0, count1 = 0;

搁置, 类似的问答。

错误是由于您的 int index;

的未初始化行为造成的

如前所述,您正在使用未初始化的变量索引。

int index;

在这个for循环中

for(int i = 0, b = strlen(inputString); i < b -1 ; i++)
{    count = 0;
    if(inputString[i] == '*')
    {
        continue;
    }else 
    {        
        for(int j = i+1; j < b ;j++)
        {           
          if(inputString[i] == inputString[j] )
            {                     
              inputString[j] = '*';
              count++;
              index = i;
            }
      
        }
     inputString[index] = '*';
    }

如果在 else 语句的内部 for 循环中找不到重复的字符,导致未定义的行为。

或者您可以使用它在上一次循环迭代后保留的变量索引的无效值。

也不是所有满足条件的字符

          if(inputString[i] == inputString[j] )

替换字符“*”。

但无论如何你的做法都是无效的。您不得更改原始字符串。否则在调用您的函数后,调用者将处理修改后的字符串。

函数可以这样写,如下面的演示程序所示。

#include <stdio.h>

int can_be_palindrome( const char *s )
{
    size_t odd = 0;
    
    for ( const char *p = s; odd < 2 && *p; ++p )
    {
        const char *q = s;
        
        while ( q != p && *q != *p ) ++q;
        
        if ( q == p )
        {
            size_t n = 1;
            while ( *++q )
            {
                if ( *q == *p ) ++n;
            }
            
            odd += n % 2;
        }
    }
    
    return odd < 2;
}

int main(void) 
{
    const char *s = "abbcabb";
    
    printf( "\"%s\" can be a palindrome is %s\n", 
            s, can_be_palindrome( s ) ? "true" : "false" );
            
    s = "aabb";
    
    printf( "\"%s\" can be a palindrome is %s\n", 
            s, can_be_palindrome( s ) ? "true" : "false" );
            
    s = "zyyzzzzz";
    
    printf( "\"%s\" can be a palindrome is %s\n", 
            s, can_be_palindrome( s ) ? "true" : "false" );
            
    s = "abca";
    
    printf( "\"%s\" can be a palindrome is %s\n", 
            s, can_be_palindrome( s ) ? "true" : "false" );
            
    return 0;
}

程序输出为

"abbcabb" can be a palindrome is true
"aabb" can be a palindrome is true
"zyyzzzzz" can be a palindrome is true
"abca" can be a palindrome is false