【问题标题】:Segmentation fault while working with decrement in for loop在 for 循环中使用减量时出现分段错误
【发布时间】:2017-02-01 20:43:48
【问题描述】:

我正在尝试在 c++ 中实现一个函数,该函数使用 Needleman-Wunsch 算法反向计算得分矩阵,但出现分段错误 11。

#include <string>
#include <vector>

int w(char x, char y){
        if (x == y){return 0;
        }else{return 1;
        }
    };

void compute_SM(std::string const & seq1, std::string const & seq2)
{

    int ws_cases[3];

    std::string m_seq1 = seq1 + " ";
    std::string m_seq2 = seq2 + " ";

    std::vector<int> rows(m_seq1.size(),0);
    std::vector<std::vector<int>> matrix(m_seq2.size(), rows);

    for (int i = 1; i< m_seq1.size(); i++){rows[i] = i*1;};
    for (int i = 1; i< m_seq2.size(); i++){matrix[0][i] = i*1;};

    for (unsigned int j = m_seq1.size()-1;j >= 1; j--){
        for (unsigned int i = m_seq2.size()-1;i  >= 1; i--){
            ws_cases[0] = matrix[i+1][j+1] + w(m_seq1[j],m_seq2[i]);
            ws_cases[1] = matrix[i+1][j] + 1;
            ws_cases[2] = matrix[i][j+1] + 1;
            matrix[i][j] = *std::max_element(ws_cases, ws_cases+3);
        }
    }

}

int main(int argc, char** argv){
    compute_SM("BANANAS", "BANDS");
}

【问题讨论】:

  • int i = 1 看起来很可疑。在 c++ 中,索引从 0 开始。
  • 通常是的,但在这种情况下我不需要覆盖 0 索引上的值
  • i*1 是干什么用的?
  • 请给我们something compilable。换句话说,这里需要minimal reproducible example
  • 你认为=&gt; 是什么意思?

标签: c++ string for-loop matrix segmentation-fault


【解决方案1】:

我不熟悉 Needleman-Wunsch 算法,但是在快速查看您发布的代码后,该行的分段错误

ws_cases[0] = matrix[i+1][j+1] + w(m_seq1[j],m_seq2[i]);

在循环的第一次迭代中发生,此时j = m_seq1.size()-1i = m_seq2.size()-1i + 1j + 1 超出范围。此外,以这种方式迭代,这些值是未初始化的。

另外,查看wiki page,您似乎应该在字符串之前放置空格:

std::string m_seq1{" " + seq1};  
std::string m_seq2{" " + seq2};

【讨论】:

    【解决方案2】:

    您已将 j 声明为 unsigned int,并假设 m_seq1.size() = 0,在这种情况下, m_seq1.size() -1= 0-1=-1 即; unsigned int j = -1,会导致运行时分段错误。

     for (unsigned int j = m_seq1.size()-1;j => 0; j--) //.j is declared unsigned, hence it must not be negative
     /* if m_seq1.size() = 0, then j = -1 : error
    

    还有 正如您的代码所建议的那样,最初您分配的是 matrix[0][i] = i*1;,但随后仅在循环开始时,您使用 ws_cases[0] = matrix[i+1][j+1] 分配+ w(m_seq1[j],m_seq2[i]);如果 i = 1 j= 1(say),matrix[2][2] 未初始化,因此可能包含垃圾,可能导致分段错误或代码转储

    【讨论】:

    • 我使用了 gdb 调试器,似乎错误发生在 'ws_cases[0] = matrix[i+1][j+1] + w(m_seq1[j],m_seq2[i] );'
    • 嗨,正如您的代码所建议的,最初您分配的是 matrix[0][i] = i*1;,但随后仅在循环开始时,您使用 ws_cases[0] = matrix 分配[i+1][j+1] + w(m_seq1[j],m_seq2[i]);如果 i = 1 j= 1(say),matrix[2][2] 未初始化,因此可能包含垃圾,可能导致分段错误或代码转储
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-26
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-01
    相关资源
    最近更新 更多