在 for 循环中使用递减时出现分段错误

Segmentation fault while working with decrement in for loop

本文关键字:分段 错误 循环 for      更新时间:2023-10-16

我正在尝试在 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");
}

我不熟悉 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 页面,似乎您应该在字符串之前放置空格:

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

您已将 j 声明为无符号整数,并假设 m_seq1.size() = 0,在这种情况下,m_seq1.size() -1= 0-1=-1 即;无符号 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

也正如您的代码所建议的,最初您正在分配矩阵 [0][i] = i*1;,但仅在循环开始时,您使用 ws_cases[0] = 矩阵[i+1][j+1] + w(m_seq1[j],m_seq2[i]); 如果 i = 1 j= 1(比如说),矩阵 [2][2] 未初始化,因此可能包含垃圾,这可能导致隔离错误或代码转储