【问题标题】:Segmentation error when trying to access element of a multidimensional array in C++尝试在 C++ 中访问多维数组的元素时出现分段错误
【发布时间】:2021-05-08 14:08:22
【问题描述】:

我有一个二维数组和一个一维向量。 我的任务是编写一个程序,分配给向量的第 i 个分量

  1. 矩阵第i行的第一个元素,如果该行至少有一个负元素,
  2. 第 i 行的最后一个元素,如果没有的话。 这是我所做的。
#include <iostream>
#include <cmath>
using namespace std;
    
int main() {
    double matrix[4][4] = {{1.3, -5.0, 4.4, 3.0}, {7.0, 4.0, 2.01, 1.0}, {7.0, 12.3, -8.7, 9.0}, {4.0, 1.0, 33.0, 63.3}};
    
    double vector[4];
    for(int i = 0; i < 4; i++) {
            bool rowHasNegNum = false;
            for(int j = 0; j < 4; i++) {
                if (matrix[i][j] < 0) {
                    rowHasNegNum = true;
                }
            }
            if(rowHasNegNum) {
                vector[i] = matrix[i][0];
            } else {
                vector[i] = matrix[i][3];
            }
    }
    

        
    for(int i=0; i<4; i++) {
        cout<<vector[i]<<"\t";
    }
    cout<<endl;
    
    return 0;
}

但是当我编译程序时,我得到以下错误。有什么问题?

Segmentation fault (core dumped)

【问题讨论】:

  • 不相关,但使用vector 作为变量名是个糟糕的主意。
  • @KamilCuk 非常感谢,我更正了它,我的程序按预期工作:)
  • @M.A 谢谢你的建议,确实......
  • @M.A 强烈不同意。它可以是一个完全合适的变量名。
  • @M.A 在这种情况下,问题毫无疑问是using namespace std,而不是使用完全合理的名称。

标签: c++ algorithm loops for-loop multidimensional-array


【解决方案1】:

故障在这里for (int j = 0; j &lt; 4; i++)。您没有递增j,而是递增i。并且由于j 没有递增,i 递增通过数组的边界。这就是分段错误的原因。

解决方法很简单,只需在此处将ij 交换即可,

for (int j = 0; j < 4; j++)

【讨论】:

    【解决方案2】:

    对于初学者来说,这个头文件都没有声明

    #include <cmath>
    

    在程序中使用。所以删除它。

    不要在这些语句中使用像 43 这样的幻数

    for(int i = 0; i < 4; i++)
    
    ector[i] = matrix[i][3];
    

    改为使用命名常量。

    在这个for循环中

     for(int j = 0; j < 4; i++) {
                           ^^^
    

    有一个错字。你需要写

     for(int j = 0; j < 4; j++) {
                           ^^^
    

    这个for循环

            bool rowHasNegNum = false;
            for(int j = 0; j < 4; j++) {
                if (matrix[i][j] < 0) {
                    rowHasNegNum = true;
                }
            }
    

    一旦发现负数就应该中断。

    你也可以使用标准算法std::any_of来代替这个for循环。

    在这种情况下,您的程序可能如下所示

    #include <iostream>
    #include <functional>
    #include<iterator>
    #include<algorithm>
    
    int main() 
    {
        const size_t N = 4;
        double matrix[N][N] = 
        {
            { 1.3, -5.0,  4.4,  3.0 }, 
            { 7.0,  4.0,  2.01, 1.0 }, 
            { 7.0, 12.3, -8.7,  9.0 }, 
            { 4.0,  1.0, 33.0, 63.3 }
        };
        
        double vector[N];
        
        size_t i = 0;
        
        for ( const auto &row :matrix )
        {
            using std::placeholders::_1;
            if ( std::any_of( std::begin( row ), std::end( row ), 
                              std::bind( std::less<>( ), _1, 0 ) ) )
            {
                vector[i++] = row[0];
            }
            else
            {
                vector[i++] = row[N-1];
            }
        }
        
        for ( const auto &item : vector )
        {
            std::cout << item << ' ';
        }
        std::cout << '\n';
        
        return 0;
    }
    

    程序输出是

    1.3 1 7 63.3 
    

    如果只使用循环,那么程序可以如下所示

    #include <iostream>
    
    int main() 
    {
        const size_t N = 4;
        double matrix[N][N] = 
        {
            { 1.3, -5.0,  4.4,  3.0 }, 
            { 7.0,  4.0,  2.01, 1.0 }, 
            { 7.0, 12.3, -8.7,  9.0 }, 
            { 4.0,  1.0, 33.0, 63.3 }
        };
        
        double vector[N];
        
        for ( size_t i = 0; i < N; i++ )
        {
            bool rowHasNegNum = false;  
            
            for ( size_t j = 0; not rowHasNegNum && j < N; j++ )
            {
                rowHasNegNum = matrix[i][j] < 0;
            }
            
            vector[i] = rowHasNegNum ? matrix[i][0] : matrix[i][N-1];       
        }
        
        for ( const auto &item : vector )
        {
            std::cout << item << ' ';
        }
        std::cout << '\n';
        
        return 0;
    }
    

    【讨论】:

      【解决方案3】:
       for(int j = 0; j < 4; i++) {
      

      您在这里增加了错误的变量。编译器警告选择了这个,你应该确保你启用了警告。

      通过在此循环中增加 i,您正在访问数组之外​​的值,从而导致分段错误。

      【讨论】:

      • 谢谢,我的程序成功了。如何启用警告?我正在使用在线编译器
      • @ArmanGrigoryan 取决于你使用哪个,你应该能够在某个地方设置编译标志,你可以在其中添加 -Wall 大致代表所有警告
      猜你喜欢
      • 2023-04-10
      • 2022-01-21
      • 1970-01-01
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多