Resizing a Matrix

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;

}
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
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.