【问题标题】:Why am I getting "runtime error: Segmentation fault" for random test cases?为什么随机测试用例会出现“运行时错误:分段错误”?
【发布时间】:2021-06-08 19:21:20
【问题描述】:

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

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

这是我的代码:

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 上的街机部分/介绍下解决这个问题。 Q.18 回文重排。

【问题讨论】:

  • 您是否使用调试器单步调试代码并找出发生分段错误的位置?
  • 索引未初始化,可能是随机的。
  • 正如@VladfromMoscow 所说,你写的没有任何意义。 1) '*' 可以是字符串的一部分; 2)你是随机主演的; 3) 只需确保所有字符出现偶数次,最多 1 个字符出现奇数次。
  • @CostantinoGrana ...因为它在我的回答中实现了。:)
  • @VladfromMoscow 没错!

标签: c c-strings palindrome function-definition


【解决方案1】:

正如已经提到的,您正在使用未初始化的变量索引。

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

【讨论】:

    【解决方案2】:

    “为什么随机测试用例会出现“运行时错误:分段错误”?”

    除了你的函数在逻辑上不能用于测试回文之外,由于undefined behavior,它会在随机情况下失败:

    int index;
    

    未初始化,

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

    inputString[index] = '*';
    

    使用以下运行时消息序列:

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

    int index;
    int count, count1 = 0;
    

    到这里:

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

    除此之外,here is an example 的类似问题和答案。

    【讨论】:

      【解决方案3】:

      错误是由于您的 int index; 的未初始化行为引起的

      【讨论】:

      • 仅供参考 - 在编辑框中,unintializedbhehaviour 下方的红色波浪线表示拼写错误的单词。如果您在这些单词上单击鼠标右键,则会出现建议的拼写更正列表。
      • 您还知道您可以随时编辑您的答案吗?只需点击答案下方的编辑。 (而且我不是反对者。)
      • 哥们,我来这里是为了获得并提供我没有投票的知识:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-23
      相关资源
      最近更新 更多