首页 > 解决方案 > 读取用户输入会导致分段错误,但硬编码时输入不同

问题描述

在发布此问题之前,我检查了与分段错误相关的现有问题,但我无法解决我的错误。
我正在尝试为以下输入运行 c++ 程序,但我面临分段错误错误。

输入:

4
gitohro qf ejvh i
3
gor
pih
sto

预期输出:

gitohro i

当我在程序中对输入进行硬编码时,我得到了预期的输出。但是当我从用户/控制台获取输入时,我得到了 Segmentation fault 错误。

实际错误信息:

/bin/sh:第 1 行:22094 分段错误:11 gtimeout 4s ./main < input.txt > output.txt [在 1.3 秒内完成,退出代码 139] [cmd: ['g++-11 main.cpp -o main && gtimeout 4s ./main<input.txt>output.txt']]

我检查了所有索引以查看它是否是数组超出范围的问题,但我不确定我做错了什么。 请指导。

我的完整代码:

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

    struct node{    //TrieNode
        char c;
        int ends;
        string word;
        node *child[26];
    };
    struct node *getNode(char c)    //get newnode
    {
        node *newnode = new node;
        newnode->c = c;
        newnode->ends = 0;
        newnode->word = "";
        for(int i=0;i<26;++i)
            newnode->child[i] = NULL;
        return newnode;
    }
    node *root = getNode('/');  //root
    
    //Trie INSERT
    void insert(string s)
    {
        node *curr=root;
        int index,i=0;
        while(s[i])
        {
            index = s[i]-'a';
            if(curr->child[index]==NULL)
                curr->child[index] = getNode(s[i]);
            
            curr=curr->child[index];
            i+=1;
        }
        curr->ends += 1;
        curr->word = s;
    }
    
    void solve(vector<vector<char>>& board,int i,int j,int r,int c,vector<string>& ans,node *curr)
    {
        //Base case
        //If the trie doesn't have the current char OR cell is Visited
        int index = board[i][j]-'a';
        if(board[i][j]=='$' || curr->child[index]==NULL)  
            return;
        
        curr = curr->child[index];
        if(curr->ends > 0)
        {
            ans.push_back(curr->word);
            curr->ends -=1;
        }
        
        //Body
        char ch = board[i][j];   //Store current char
        board[i][j] = '$';  //Mark current node visited
        
        if(i>0)     //TOP
            solve(board,i-1,j,r,c,ans,curr);
        if(i<r-1)   //DOWN
            solve(board,i+1,j,r,c,ans,curr);
        if(j>0)     //LEFT
            solve(board,i,j-1,r,c,ans,curr);
        if(j<c-1)   //RIGHT
            solve(board,i,j+1,r,c,ans,curr);
        if(i>0 && j>0)     //TOP LEFT
            solve(board,i-1,j-1,r,c,ans,curr);
        if(i<r-1 && j>0)   //DOWN LEFT
            solve(board,i+1,j-1,r,c,ans,curr);
        if(i<r-1 && j<c-1)     //DOWN RIGHT
            solve(board,i+1,j+1,r,c,ans,curr);
        if(i>0 && j<c-1)   //TOP RIGHT
            solve(board,i-1,j+1,r,c,ans,curr);
        
        board[i][j] = ch;    //Mark current node as Unvisited by restoring the value
    }
    
    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {        
        int r=board.size();
        int c=board[0].size();
        
        //Insert all words in TRIE
        for(int i=0;i<words.size();++i)
            insert(words[i]);
        
        //Now search words
        vector<string> ans;
        for(int i=0;i<r;++i)
        {
            for(int j=0;j<c;++j)
                solve(board,i,j,r,c,ans,root);
        }
        return ans;
    }

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("input.txt",  "r",  stdin);
        freopen("output.txt", "w", stdout);
    #endif    
    vector<string> w ;    
    vector<vector<char>> x;   
    int o,p;
    cin>>o;
    for (int i = 0; i < o; ++i)
    {
        cin>>w[i];
    }
    cin>>p;

    for (int i = 0; i < p; ++i)
    {
        for (int j = 0; j < p; ++j)
        {
            cin>>x[i][j];
        }
    }    

    /*
    vector<string> w = {"gitohro", "qf", "ejvh", "i"};
    vector<vector<char>> x = {
                            {'g','o','r'},
                            {'p','i','h'},
                            {'s','t','o'}                           
                        };
    */
    vector<string> res = findWords(x,w);
    
    for(auto i:res)
        cout<<i<<" ";  

    return 0;
}


/*
Input 1:
4
gitohro qf ejvh i 
3
gor
pih
sto

Output 1:
gitohro i 

*/

标签: c++segmentation-fault

解决方案


main()正在将用户输入读入空向量。您没有向它们添加任何条目,因此您的使用vector::operator[]会导致未定义的行为(如果您要替换vector::operator[]vector::at(),则会std::out_of_range引发异常)。

当您对输入进行硬编码时,您正在vector正确地使用实际条目填充 s。

要解决此问题,请尝试以下操作:

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("input.txt",  "r",  stdin);
        freopen("output.txt", "w", stdout);
    #endif

    vector<string> w;
    vector<vector<char>> x;
    int o, p;

    cin >> o;
    w.resize(o); // <-- ADD THIS!
    for (int i = 0; i < o; ++i)
    {
        cin >> w[i];
    }

    cin >> p;
    x.resize(p, vector<char>(p)); // <-- ADD THIS!
    for (int i = 0; i < p; ++i)
    {
        for (int j = 0; j < p; ++j)
        {
            cin >> x[i][j];
        }
    }    

    vector<string> res = findWords(x, w);
    
    for(auto i : res)
        cout << i << " ";  

    return 0;
}

或者:

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("input.txt",  "r",  stdin);
        freopen("output.txt", "w", stdout);
    #endif

    int o, p;

    cin >> o;
    vector<string> w(o); // <-- INIT HERE!
    for (int i = 0; i < o; ++i)
    {
        cin >> w[i];
    }

    cin >> p;
    vector<vector<char>> x(p, vector<char>(p)); // <-- INIT HERE!
    for (int i = 0; i < p; ++i)
    {
        for (int j = 0; j < p; ++j)
        {
            cin >> x[i][j];
        }
    }    

    vector<string> res = findWords(x, w);
    
    for(auto i : res)
        cout << i << " ";  

    return 0;
}

或者,使用vector::push_back()代替vector::operator[]

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("input.txt",  "r",  stdin);
        freopen("output.txt", "w", stdout);
    #endif

    vector<string> w;
    vector<vector<char>> x
    int o, p;

    cin >> o;
    w.reserve(o);
    for (int i = 0; i < o; ++i)
    {
        string s;
        cin >> s;
        w.push_back(s);
    }

    cin >> p;
    x.reserve(p);
    for (int i = 0; i < p; ++i)
    {
        vector<char> v;
        v.reserve(p);
        for (int j = 0; j < p; ++j)
        {
            char ch;
            cin >> ch;
            v.push_back(ch);
        }
        x.push_back(v):
    }    

    vector<string> res = findWords(x, w);
    
    for(auto i : res)
        cout << i << " ";  

    return 0;
}

推荐阅读