Loading vector with bit matrices

I have a code segment here that loads zeroes into a vector that represents a bit matrix. When the program runs and tries to write the result in a output file I get a seg fault. The program runs fine when it does not write in the output file.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Bitmatrix::Bitmatrix(int rows, int cols)
{
    int count = 0;                                                                          // count variable
    int count2 = 0;                                                                        // 2nd count variable

    if( rows <= 0 || cols <= 0 )
    {
        fprintf( stderr, "Value of rows or columns is less than or equal to zero\n" );  // print error message
        M.resize( 1 );                                                                 // resize to 1 x 1 matrix
        M[0] = '0';                                                                   // set 0 as the value
    }
    else
        M.resize( rows );                                                           // resize matrix to number of rows
        for( count = 0; count < M.size(); count++ )
        {
            for( count2 = 0; count2 < cols; count2++ )
            {
                M[count].push_back( '0' );                                       // fill matrix with zeros  
            }
        }
}


The function that prints in the output file is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void Bitmatrix::Write(string fn)
{
    ofstream out;                                                      // output stream object
    int count = 0;                                                    // count variable
    int count2 = 0;                                                  // 2nd count variable

    out.open( fn.c_str() );                                        // open output file
    for( count = 0; count < M.size(); count++ )
    {
        for( count2 = 0; count2 < M[count].size(); count++ )
        {
            out << M[count][count2];
        }
        out << endl;
    }
}


Can anyone see why this is happening?
Last edited on
This may not help you much, but you did not close the file when you are done writing.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void Bitmatrix::Write(string fn)
{
    ofstream out;                                                      // output stream object
    int count = 0;                                                    // count variable
    int count2 = 0;                                                  // 2nd count variable

    out.open( fn.c_str() );                                        // open output file
    for( count = 0; count < M.size(); count++ )
    {
        for( count2 = 0; count2 < M[count].size(); count++ )
        {
            out << M[count][count2];
        }
        out << endl;
    }
    out.close();
}
Thanks for pointing that out and no it did not stop the seg fault. Any clue on why its happening?
A pretty clear logic error there.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    if( rows <= 0 || cols <= 0 )
    {
        fprintf( stderr, "Value of rows or columns is less than or equal to zero\n" );  // print error message
        M.resize( 1 );                                                                 // resize to 1 x 1 matrix
        M[0] = '0';                                                                   // set 0 as the value
    }
    else
        M.resize( rows );                                                           // resize matrix to number of rows
        for( count = 0; count < M.size(); count++ )
        {
            for( count2 = 0; count2 < cols; count2++ )
            {
                M[count].push_back( '0' );                                       // fill matrix with zeros  
            }
        }


Should be :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    if( rows <= 0 || cols <= 0 )
    {
        fprintf( stderr, "Value of rows or columns is less than or equal to zero\n" );  // print error message
        M.resize( 1 );                                                                 // resize to 1 x 1 matrix
        M[0] = '0';                                                                   // set 0 as the value
    }
    else
    {
        M.resize( rows );                                                           // resize matrix to number of rows
        for( count = 0; count < M.size(); count++ )
        {
            for( count2 = 0; count2 < cols; count2++ )
            {
                M[count].push_back( '0' );                                       // fill matrix with zeros  
            }
        }
    }
Is the change just brackets around the else block because that does not help the problem.
I did not say that would fix your problem.
Anyways, can you post your whole Bitmatrix class (and your function main() if possible)? I need more information.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <string>
#include <iostream>
#include <vector>
using namespace std;

class Bitmatrix {
  public:
    Bitmatrix(string fn);            // Read from a file
    Bitmatrix(int rows, int cols);   // Create an empty bitmatrix
    void Print(int w);               // Print it on standard ouptput with spaces & blank lines 
    void Write(string fn);           // Write it to a file either as hex or zeros & ones
    void PGM(string fn, int pixels, int border);  // Write it to a pgm file 
    int Rows();
    int Cols();
    void Set(int row, int col, char val); // Set the specified element to val
    char Val(int row, int col);           // Return the specified element
    void Swap_Rows(int r1, int r2);
    void R1_Plus_Equals_R2(int r1, int r2);
    Bitmatrix *Copy();
  protected:
    vector <string> M; // The matrix.  Elements are '0' or '1'.
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
main(int argc, char **argv)
{
  Bitmatrix *bm, *bm2, *bm3, *bm4, *bm5;
  BM_Hash *ht;
  int i, r, c, w, v, p, b;
  string s;
  vector <string> sv;
  istringstream ss;
  string prompt = "";
  HTVec all;
  vector <int> ind;

  if (argc > 2) {
    cerr << "usage: matrix_editor [prompt]\n";
    exit(1);
  }
  if (argc == 2) prompt = argv[1];
  if (prompt.size() > 0) prompt += " ";
  bm = NULL;

  ht = new BM_Hash(10000);
  while (1) {

    cout << prompt;
    cout.flush();

    if (!getline(cin, s)) exit(0);
    sv = StoSVec(s);
    if (sv.size() > 0 && sv[0][0] != '#') {
      if (sv[0] == "EMPTY") {
        if (sv.size() != 3 || sscanf(sv[1].c_str(), "%d", &r) != 1 || r <= 0 ||
                              sscanf(sv[2].c_str(), "%d", &c) != 1 || c <= 0) {
          printf("Should be: EMPTY rows cols\n");
        } else {
          if (bm != NULL) delete bm;
          bm = new Bitmatrix(r, c);
           }
      } else if (sv[0] == "SET") {
        if (sv.size() != 4 || sscanf(sv[1].c_str(), "%d", &r) != 1 || r < 0 ||
                              sscanf(sv[2].c_str(), "%d", &c) != 1 || c < 0 ||
                              (sv[3] != "0" && sv[3] != "1")) {
          printf("Should be: SET r c 0|1\n");
        } else if (bm == NULL) {
          printf("No current matrix.\n");
        } else if (r >= bm->Rows()) {
          printf("r must be less than %d\n", bm->Rows());
        } else if (c >= bm->Cols()) {
          printf("c must be less than %d\n", bm->Cols());
        } else {
          bm->Set(r, c, sv[3][0]);
        }
      } else if (sv[0] == "VAL") {
        if (sv.size() != 3 || sscanf(sv[1].c_str(), "%d", &r) != 1 || r < 0 ||
                              sscanf(sv[2].c_str(), "%d", &c) != 1 || c < 0) {
          printf("Should be: VAL r c\n");
        } else if (bm == NULL) {
          printf("No current matrix.\n");
        } else if (r >= bm->Rows()) {
          printf("r must be less than %d\n", bm->Rows());
        } else if (c >= bm->Cols()) {
          printf("c must be less than %d\n", bm->Cols());
        } else {
          printf("%d\n", bm->Val(r, c));
        }
      } else if (sv[0] == "SWAP") {
        if (sv.size() != 3 || sscanf(sv[1].c_str(), "%d", &r) != 1 || r < 0 ||
                              sscanf(sv[2].c_str(), "%d", &c) != 1 || c < 0) {
          printf("Should be: SWAP r1 r2\n");
        } else if (bm == NULL) {
          printf("No current matrix.\n");
        } else if (r >= bm->Rows()) {
          printf("r must be less than %d\n", bm->Rows());
         } else if (c >= bm->Rows()) {
          printf("c must be less than %d\n", bm->Rows());
        } else {
          bm->Swap_Rows(r, c);
        }
      } else if (sv[0] == "+=") {
        if (sv.size() != 3 || sscanf(sv[1].c_str(), "%d", &r) != 1 || r < 0 ||
                              sscanf(sv[2].c_str(), "%d", &c) != 1 || c < 0) {
          printf("Should be: R1+=R2 r1 r2\n");
        } else if (bm == NULL) {
          printf("No current matrix.\n");
        } else if (r >= bm->Rows()) {
          printf("r must be less than %d\n", bm->Rows());
        } else if (c >= bm->Rows()) {
          printf("c must be less than %d\n", bm->Rows());
        } else {
          bm->R1_Plus_Equals_R2(r, c);
        }
      } else if (sv[0] == "PRINT") {
        w = -1;
        if (sv.size() == 1) {
          w = 0;
        } else if (sv.size() != 2 || sscanf(sv[1].c_str(), "%d", &w) != 1 || w < 0) {
          printf("Should be: PRINT [w]\n");
          w = -1;
        }
        if (w >= 0) {
          if (bm == NULL) {
            printf("No current matrix.\n");
          } else {
            bm->Print(w);
          }
        }
      } else if (sv[0] == "WRITE") {
        if (sv.size() != 2) {
          printf("Should be: WRITE filename\n");
          } else if (bm == NULL) {
          printf("No current matrix.\n");
        } else {
          bm->Write(sv[1]);
        }
      } else if (sv[0] == "PGM") {
        if (sv.size() != 4) {
          printf("Should be: PGM filename pixels border\n");
        } else if (sscanf(sv[2].c_str(), "%d", &p) == 0 || p <= 0) {
          printf("Should be: PGM filename pixels border -- pixels > 0\n");
        } else if (sscanf(sv[3].c_str(), "%d", &b) == 0 || b < 0) {
          printf("Should be: PGM filename pixels border -- border >= 0\n");
        } else {
          bm->PGM(sv[1], p, b);
        }
      } else if (sv[0] == "READ") {
        if (sv.size() != 2) {
          printf("Should be: WRITE filename\n");
        } else {
          if (bm == NULL) delete bm;
          bm = new Bitmatrix(sv[1]);
        }
      } else if (sv[0] == "STORE") {
        if (sv.size() != 2) {
          printf("Should be: STORE key\n");
        } else {
          bm2 = ht->Recall(sv[1]);
          if (bm2 != NULL) delete bm2;
          ht->Store(sv[1], bm->Copy());
        }
      } else if (sv[0] == "RECALL") {
        if (sv.size() != 2) {
          printf("Should be: RECALL key\n");
        } else {
          bm2 = ht->Recall(sv[1]);
          if (bm2 == NULL) {
           printf("No matrix with key %s\n", sv[1].c_str());
          } else {
            if (bm != NULL) delete bm;
            bm = bm2->Copy();
          }
        }
      } else if (sv[0] == "ALL") {
        if (sv.size() != 1) {
          printf("Should be: ALL\n");
        } else {
          all = ht->All();
          for (i = 0; i < all.size(); i++) {
            printf("%-30s %3d X %3d\n", all[i]->key.c_str(), all[i]->bm->Rows(), all[i]->bm->Cols());
          }
        }
      } else if (sv[0] == "SUM") {
        if (sv.size() != 3) {
          printf("Should be: SUM key1 key2\n");
        } else {
          bm2 = ht->Recall(sv[1]);
          bm3 = ht->Recall(sv[2]);
          if (bm2 == NULL) {
            printf("No matrix %s\n", sv[1].c_str());
          } else if (bm3 == NULL) {
            printf("No matrix %s\n", sv[2].c_str());
          } else if (bm2->Rows() != bm3->Rows()) {
            printf("Rows don't match\n");
          } else if (bm2->Cols() != bm3->Cols()) {
            printf("Cols don't match\n");
          } else {
            if (bm != NULL) delete bm;
            bm4 = bm2->Copy();
            bm5 = bm3->Copy();
            bm = Sum(bm2, bm3);
            check_equal(bm2, bm4);
            check_equal(bm3, bm5);
             delete bm4;
            delete bm5;
          }
        }
      } else if (sv[0] == "PRODUCT") {
        if (sv.size() != 3) {
          printf("Should be: PRODUCT key1 key2\n");
        } else {
          bm2 = ht->Recall(sv[1]);
          bm3 = ht->Recall(sv[2]);
          if (bm2 == NULL) {
            printf("No matrix %s\n", sv[1].c_str());
          } else if (bm3 == NULL) {
            printf("No matrix %s\n", sv[2].c_str());
          } else if (bm2->Cols() != bm3->Rows()) {
            printf("Dimensions don't match\n");
          } else {
            bm4 = bm2->Copy();
            bm5 = bm3->Copy();
            if (bm != NULL) delete bm;
            bm = Product(bm2, bm3);
            check_equal(bm2, bm4);
            check_equal(bm3, bm5);
            delete bm4;
            delete bm5;
          }
        }
      } else if (sv[0] == "SUBMATRIX") {
        if (sv.size() < 2) {
          printf("Should be: SUBMATRIX rows...\n");
        } else if (bm == NULL) {
          printf("No matrix %s\n", sv[1].c_str());
        } else {
          ind.clear();
          for (i = 1; i < sv.size(); i++) {
            if (sscanf(sv[i].c_str(), "%d", &r) != 1 || r < 0 || r >= bm->Rows()) {
               printf("Bad row %s. Should be a number between 0 and %d\n",
                sv[i].c_str(), bm->Rows()-1);
              i = sv.size() + 10;
            } else {
              ind.push_back(r);
            }
          }
          if (i == sv.size()) {
            bm3 = bm->Copy();
            bm2 = Sub_Matrix(bm, ind);
            check_equal(bm, bm3);
            delete bm3;
            delete bm;
            bm = bm2;
          }

The end is cut off because its too long which is why I was hesitant to post at first
What is your assignment all about?
It loads bit matrices in a vector that stores only ones and zeroes. It is supposed to create, read, write, and manipulate the matrix. It also has another class that stores the matrices in a hash table( I have not started on that yet).
Did you miss the correction SakurasaoBusters offered in void Bitmatrix::Write(string) -- check the inner loop, line 10 of your code snippet?
I did. I don't see any correction for that function. Can you please elaborate?
Why are you using printf, sscanf, scanf, fprintf etc? That is C code style.
They are not type-safe and I recommend not using any of them.
Last edited on
That's what I was taught. Sometimes it is easier to format with them.
In your Write() method:

8
9
10
11
12
13
14
15
    for( count = 0; count < M.size(); count++ )
    {
        for( count2 = 0; count2 < M[count].size(); count++ )
        {
            out << M[count][count2];
        }
        out << endl;
    }


in the inner loop, you're incrementing the wrong variable.
Last edited on
Topic archived. No new replies allowed.