【问题标题】:Segmentation Fault on input of string of size 1输入大小为 1 的字符串时出现分段错误
【发布时间】:2020-03-30 07:23:48
【问题描述】:

当我将大小为 1 的字符串作为输入传递时,我遇到了分段错误(核心转储)。我试图寻找原因,但我找不到任何原因,我被要求调试我的程序。通过调试,我意识到它在读取大小为 1 的字符串时会引发分段错误。

#include<bits/stdc++.h>
#define ll long long
using namespace std;

int main()
{
    ll t,x,y;
    string s;
    cin>>t;
    while(t--){
        cin>>s;
        int tilt=0;
        for(int i=s.length()-1,j=0;i>=s.length()/2;i--,j++){
            if(s[i]!=s[j]){
                tilt = s[i]>s[j]?-1:1;
                s[i]=s[j];
            }
        }
        if(tilt==-1 || tilt==0){
            if(s.length()%2==0){
                y=1;x=s.length()/2-1;
                while(y!=0 && x>=0){
                    if(s[x]=='9'){
                        s[x]='0';
                    }else{
                        s[x] += 1;
                        y=0;
                    }
                    x--;
                }
                if(y==0){
                    for(int i=0;i<s.length()/2;i++){
                        cout<<s[i];
                    }
                    for(int i=s.length()/2-1;i>=0;i--){
                        cout<<s[i];
                    }
                    cout<<endl;
                }else{
                    cout<<1;
                    for(int i=0;i<s.length()/2;i++){
                        cout<<s[i];
                    }
                    for(int i=s.length()/2-2;i>=0;i--){
                        cout<<s[i];
                    }
                    cout<<1<<endl;
                }
            }else{
                y=1;x=s.length()/2;
                while(y!=0 && x>=0){
                    if(s[x]=='9'){
                        s[x]='0';
                    }else{
                        s[x] += 1;
                        y=0;
                    }
                    x--;
                }
                if(y==0){
                    for(int i=0;i<s.length()/2;i++){
                        cout<<s[i];
                    }
                    for(int i=s.length()/2;i>=0;i--){
                        cout<<s[i];
                    }
                    cout<<endl;
                }else{
                    cout<<1;
                    for(int i=0;i<s.length()/2;i++){
                        cout<<s[i];
                    }
                    for(int i=s.length()/2-1;i>=0;i--){
                        cout<<s[i];
                    }
                    cout<<1<<endl;
                }
            }
        }else{
            cout<<s<<endl;
        }
    }
    return 0;
}

输入: 1 11 输出: 22

输入: 1 1 输出: 错误

问题:https://www.spoj.com/problems/PALIN/

【问题讨论】:

    标签: c++ segmentation-fault palindrome


    【解决方案1】:

    这里

    for(int i=s.length()-1,j=0;i>=s.length()/2;i--,j++){
    

    s 的大小为 1 时,s.length()/2 是一个值为 0 的 无符号 量。将整数与无符号数进行比较时,在比较之前将整数转换为无符号数。检查无符号值是否 >= 0 始终为真,因此这是一个无限循环。这就是它崩溃的原因。

    我希望您的编译器能够警告您有符号/无符号比较的危险。

    这是修复这个特定循环的一种方法,但我猜你的代码中的其他地方也有类似的问题。

    for (size_t i = s.length(), j = 0; i > s.length()/2; ++j) {
        --i;
        if (s[i] != s[j]) {
            tilt = s[i] > s[j] ? -1 : 1;
            s[i] = s[j];
        }
    }
    

    一些建议

    • size_t 用于索引变量。
    • 当向后循环时要非常小心终止条件,我这样做的方法是使变量比它需要的大一并在循环开始而不是结束时递减它。这样您就可以与&gt; 而不是&gt;= 进行比较,从而避免代码出现的问题。
    • 尝试在代码中使用一些空格。它让每个人都更容易阅读,包括您自己。

    【讨论】:

    • 感谢约翰的回答,但即使我尝试在此 for 循环之前打印“*”,它也会失败。它永远不会到达 for 循环。
    • @Ayush 我不明白这是怎么可能的,在那个循环之前只有几行代码,而且它们都不会导致崩溃。 ll t,x,y; string s; cin&gt;&gt;t; while(t--){ cin&gt;&gt;s; int tilt=0; 可能你误解了我说的是哪个循环?
    • @Ayush 打印"*" 也不是诊断性的。输出是缓冲的,所以仅仅因为你没有看到* 并不意味着它没有被打印出来。你应该像这样打印cout &lt;&lt; "*" &lt;&lt; flush; 以确保输出立即出现(cout &lt;&lt; "*" &lt;&lt; endl; 也有效)。
    • 非常感谢,您说的完全正确。我自己永远也想不通。您的指示非常有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-31
    • 1970-01-01
    • 2021-09-26
    • 2020-06-24
    相关资源
    最近更新 更多