简体   繁体   中英

C++: Copy elements of matrix class to an array

I have this method (Matrix::WriteToArray(double &CopyOfArray)) that I want to write a copy of an array in the Matrix object to an array of doubles (ie CopyOfArray). I am having trouble compiling though.

Any help is appreciated. Thanks

Error:

$ make
g++ -g -Wall -c main.cpp
main.cpp: In function ‘int mrstart(double, double*, Matrix&, Matrix&)’:
main.cpp:459:13: error: ‘cff’ declared as reference but not initialized
main.cpp:465:45: error: invalid type argument of unary ‘*’
main.cpp:467:73: error: invalid type argument of unary ‘*’
main.cpp:470:77: error: invalid type argument of unary ‘*’
Makefile:20: recipe for target `main.o' failed
make: *** [main.o] Error 1

Here are the supporting files: Main.cpp

int mrstart(double hcen, double mr[],  Matrix &a,  Matrix &HT)
{
    double *cff;
    a.WriteToArray(&cff);
    /*...*/
}

Matrix.cc

int Matrix::WriteToArray(double &CopyOfArray){
    int i;
    for(i=0;i<n_rows;i++){
        CopyOfArray[i]=array[i*n_cols];
        i++;
    }
    return *CopyOfArray;
}

Matrix.hh

#ifndef MATRIX_H
#define MATRIX_H
// Matrix class of variable size
class Matrix {

private:
    int n_rows;
    int n_cols;
    double *array;

public:
    // Constructors
    Matrix(); // default constructor
    Matrix(int rows, int cols); // two-argument constructor
//  Matrix(const Matrix &arr); // copy constructor


    // Destructor
    ~Matrix();

    // Mutators
//  void add(Matrix m2);
//  void subtract(Matrix m2);
    void setelem(int r, int c, double val);

    // Accessors
//  void add(Matrix m2);
//  void subtract(Matrix m2);
    int getrows();
    int getcols();
    double getelem(int r, int c);
    bool equals(Matrix m2);
    char display();
    int WriteToArray(double &CopyOfArray);

};
#endif

You want

int Matrix::WriteToArray(double CopyOfArray[], const int size){
    //make sure size >= n_rows then copy
}

and call it like so

double cff[MAX_SIZE] = {};
a.WriteToArray(cff);

You should really use std::vector and not worry about dynamic allocation.

EDIT: ok you can do manual allocation if you really want to but be careful to release it:

double* cff = 0;
a.WriteToArray(cff);
//do stuff with cff
delete [] cff;

And inside you write function

int Matrix::WriteToArray(double *dest){
 dest = new double[n_rows];
 //copy data into dest
}

The main thing is to make sure you delete dest when you are done using it in main so there is no memory leakage.

double *cff;
a.WriteToArray(&cff);

You are declaring a pointer, then using it before initializing it. You are passing the function a pointer that doesn't point to anything. You should either declare the array statically, if you know at compile time the size

double cff[16]; // 4x4 array, for example
a.WriteToArray(cff);

or size it appropriately before calling the function.

double * cff = new double[n_rows * n_cols];
a.WriteToArray(cff);

A few other criticisms: your function expects a reference to a double as an argument. If you want to receive an array, the usual way to do it is to request a pointer. A better way is not to use them at all and use some manner of smart pointer.

The method itself is broken too.

CopyOfArray[i]=array[i*n_cols];
i++;

This will result in you writing the first element of each row in the array, and leaving one space empty between them.

You need a nested loop. You also shouldn't be returning anything, you are already writing to the parameter array so the return value is redundant. You should also never return a pointer as an int, you should return it as a pointer. Better yet, though, you can initialize the pointer in the method, then return the pointer and catch it where you called it.

You also assume the array is the right size, which as your own example proved is not true. You should ALWAYS initialize pointers. Point them at 0 at the very least, like so:

double *cff = NULL; // = 0 also works, but I like pointing pointers to NULL

The method, fixed as much as I could, below:

double * Matrix::WriteToArray(){
    double * CopyOfArray = NULL;
    CopyOfArray = new double[n_rows*n_cols];
    int i, j;
    for(i=0;i<n_rows;i++){
        for(j=0;j<n_cols;j++){
        CopyOfArray[i*n_rows+j]=array[i*n_rows+j];
        i++;
        }
    }
    return CopyOfArray;
}

Then call it like so:

double *cff = NULL;
cff = a.WriteToArray();

WARNING: If you call the method without storing the return value you WILL leak memory. Don't use pointers, learn about smart pointers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM