Resizing a Matrix

Feb 20, 2013 at 4:39am
Can't figure out why this isn't copying the matrix right. I get crazy numbers whenever I try. I even tried to just label all the entries as zero, but that didn't work. Any help I could receive would be greatly appreciated.


#include <iostream>

struct matrix {

protected:
double * data;
int rows, columns, size;

public:
matrix(int row, int column) {
size = row * column;
columns = column;
rows = row;
data = new double [size];
}

double get(int row, int column);
void set(int row, int column, double value);
void resize(int row, int column);
matrix clone();
void print();
void init(double val);
};

.
.
.

void matrix::resize(int row, int column) {
if (row < 0 || column < 0) {
cout << "Invalid resize";
return;
}
int newsize = row * column;
double newarray[newsize];
for(int i=0; i<newsize; i += 1) {
newarray[i] = 0;
}
for(int i=0; i<row; i += 1) {
for(int j=0; j<column; j += 1) {
newarray[j+i*column] = data[j+i*columns];
}
}
delete [] data;
data = newarray;
size = newsize;
rows = row;
columns = column;

}
Feb 20, 2013 at 6:43am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void matrix::resize(int row, int column) {
    if (row < 0 || column < 0) {
        std::cout << "Invalid resize";
        return;
    }
    int newsize = row * column;
    double newarray[newsize];
    for(int i=0; i<newsize; i += 1) {
        newarray[i] = 0;
    }
    for(int i=0; i<row; i += 1) {
        for(int j=0; j<column; j += 1) {
            newarray[j+i*column] = data[j+i*columns];
        }
    }
    delete [] data;
    data = newarray;
    size = newsize;
    rows = row;
    columns = column;

} 


Line 7 is illegal as newsize is not a compile time constant.

If it were legal, the array declared therein only exists until the function ends, and since you set data to point to it, data doesn't point to valid memory after the function ends.

I would expect something more like this:
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
void matrix::resize(int row, int column) {

    if (row <= 0 || column <= 0) {
        std::cout << "Invalid resize";
        return;
    }

    if ( row == rows && column == columns )
        return ;

    int newsize = row * column;
    double * newData = new double[newsize] ;

    if ( row > rows || column > columns )
        std::fill(newData, newData+newsize, 0.0) ;

    unsigned rowsToCopy = row < rows ? row : rows ;
    unsigned colsToCopy = column < columns ? column : columns ;

    for ( unsigned r=0; r < rowsToCopy ; ++r )
    {
        double * srcBegin = data + (r*columns) ;
        double * srcEnd = srcBegin + colsToCopy ;
        double * dstBegin = newData + (r*column) ;

        std::copy(srcBegin, srcEnd, dstBegin) ;
    }

    delete [] data ;

    data = newData ;
    size = newsize ;
    rows = row ;
    columns = column ;
}


[Edit: But I really don't see much sense in allowing a matrix to be resizable.]
Last edited on Feb 20, 2013 at 6:47am
Feb 26, 2013 at 3:55am
Thanks for your help. I've gotten it to work, though I couldn't use any of what you've given me because of the scope of my class not covering what you've written (and I saw this too late :p).
Topic archived. No new replies allowed.