访问2D向量时的分段错误

时间:2014-04-19 21:44:44

标签: c++ vector segmentation-fault

我试图解决处理矩阵的问题,因为我使用了向量,但是当我尝试运行程序时,它显示了分段错误(核心转储)错误,并且在运行gdb时显示以下错误。

Program received signal SIGSEGV, Segmentation fault.
0x00000000004011b4 in main () at rectangles.cpp:43
if (p<A-1 && q <B-1 && M[p][q]==1 && M[p+1][q] == 1 && M[p][q+1]==1)

rectangles.cpp是:

#include <iostream>
#include <vector>
#include <string>
#include <cstdio>

using namespace std;

int main()
{
    int A,B,notRect,numRect=0;
    bool rectInc=false;
    string line;

    freopen("input.txt","rt",stdin);
    freopen("output.txt","wt",stdout);
    A=cin.get()-'0';
    cin.get();
    B=cin.get() - '0';
    cin.get();
    vector<vector<int> > M(A);
    vector<vector<int> > topLeft(2);
    vector<vector<int> > topRight(2);
    vector<vector<int> > bottomLeft(2);
    vector<vector<int> > bottomRight(2);

    for (int i = 0; i < A; i++)
    {
        getline(cin,line);
        for (int k = 0; k < line.size(); k++)
        {
            if (line.at(k)!=' ')
            {
                M[i].push_back(line.at(k)-'0');
            }

        }
    }

    for (int p = 0; p < A; p++)
    {
        for (int q = 0; q < B; q++)
        {
            if (p<A-1 && q <B-1 && M[p][q]==1 && M[p+1][q] == 1 && M[p][q+1]==1)
            {
                topLeft[0].push_back(p);
                topLeft[1].push_back(q);
            }
            if (p<A-1 && q >0 && M[p][q]==1 && M[p+1][q] == 1 && M[p][q-1]==1)
            {
                topRight[0].push_back(p);
                topRight[1].push_back(q);
            }
            if (p>0 && q <B-1 && M[p][q]==1 && M[p-1][q] == 1 && M[p][q+1]==1)
            {
                bottomLeft[0].push_back(p);
                bottomLeft[1].push_back(q);
            }
            if (p>0 && q >0 && M[p][q]==1 && M[p-1][q] == 1 && M[p][q-1]==1)
            {
                bottomRight[0].push_back(p);
                bottomRight[1].push_back(q);
            }
        }   

    }

    for (int i = 0; i < topLeft[0].size(); i++)
    {
        for (int j = 0; j < topRight[0].size();j++)
        {
            for (int k = 0; k < bottomLeft[0].size(); k++)
            {
                for (int l = 0; l < bottomRight[0].size(); l++)
                {
                    notRect=0;
                    rectInc=false;
                    if (topLeft[0][i]==topRight[0][j] && topLeft[1][i]+1<topRight[1][j] && topLeft[1][i]==bottomLeft[1][k] && topLeft[0][i]+1<bottomLeft[0][k] && bottomLeft[0][k]==bottomRight[0][l] &&  bottomLeft[1][k]+1<bottomRight[1][l]&& topRight[1][j]==bottomRight[1][l]&& topRight[0][j]+1<bottomRight[0][l])
                    {
                        for (int p = topLeft[1][i]; p < topRight[1][j]; p++)
                        {
                            if (M[topLeft[0][i]][p]!=1)
                            {
                                notRect=1;
                            }
                        }
                        if (notRect==1)
                        {
                            break;
                        }
                        for (int p = topLeft[0][i]; p < bottomLeft[0][k]; p++)
                        {
                            if (M[p][topLeft[1][i]]!=1)
                            {
                                notRect=1;
                            }
                        }
                        if (notRect==1)
                        {
                            break;
                        }
                        for (int p = bottomLeft[1][k]; p < bottomRight[1][l]; p++)
                        {
                            if (M[bottomLeft[0][k]][p]!=1)
                            {
                                notRect=1;
                            }
                        }
                        if (notRect==1)
                        {
                            break;
                        }
                        for (int p = topRight[0][j]; p < bottomRight[0][l]; p++)
                        {
                            if (M[p][topRight[1][j]]!=1)
                            {
                                notRect=1;
                            }
                        }
                        if (notRect==1)
                        {
                            break;
                        }

                        for (int z =topLeft[0][i]+1 ; z <=bottomLeft[0][k]-1 ; z++)
                        {
                            for (int t = topLeft[1][i]+1; t <= topRight[1][j]-1 ; t++)
                            {
                                if (M[z][t]==0)
                                {
                                    numRect++;
                                    rectInc=true;
                                }
                                else
                                {
                                    rectInc=false;
                                }
                                if (rectInc)
                                {
                                    break;
                                }
                            }
                            if (rectInc)
                            {
                                break;
                            }

                        }
                        if (rectInc)
                        {
                            break;
                        }
                    }
                }
            }
        }
    }

    cout<<numRect;
    return 0;

}

使用的input.txt有这个文本

6;7
0001111
0111011
0101011
0101011
0111011
0001111

请帮我理解错误并修复它。 感谢。

2 个答案:

答案 0 :(得分:0)

确保所有M[i]的长度均为B。我假设,你的第一个getline只会得到一个空行(因为你可能没有跳过它。你使用的是Windows吗?然后一个换行符将是两个字符宽)。因此,访问M[0][0]元素已经超出范围。

调试输出通常有助于查找这样的内容,并且通过M[i][j]交换M.at(i).at(j)将提供更详细的信息(因为它将执行边界检查)。

答案 1 :(得分:0)

更改以下代码:

int A,B,notRect,numRect=0;
bool rectInc=false;
string line; 
freopen("input.txt","rt",stdin);
freopen("output.txt","wt",stdout);
A=cin.get()-'0';
cin.get();
B=cin.get() - '0';
cin.get();

到:

int A=-1,B,notRect,numRect=0;
bool rectInc=false;
string line,temp;
freopen("input.txt","rt",stdin);
freopen("output.txt","wt",stdout);
getline(cin,line);
istringstream ss(line);
while (ss)
{
    if(getline(ss,temp,';'))
    {
        if(A==-1)
            A=atoi(temp.c_str());
        else
            B=atoi(temp.c_str());
    }
}

解决问题,谢谢!