Invalid Allocation Size (in derived class copy constructor) - c++

I have narrowed down my issue to a derived classes copy constructor, but I am unsure of the cause.
EDIT: M, N and Data are Private. The error I recieve is 'Invalid allocation size: 4294967295 bytes' - which I understand is caused when passing a -1 to new. I'm unsure why this would occur unless the data is lost when the class comunicate.
BinaryMatrix::BinaryMatrix(const BinaryMatrix& copy) : Matrix(copy)
{
//cout << "Copy Constructor\n";
M = copy.M;
N = copy.N;
data = new double[M*N]; //This line causes the allocation error
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
data[i*N+j] = copy.data[i*N+j];
}
}
}
The above is my derived copy constructor which causes the error. I have marked the allocation line.
I can only assume that M and N are not being read correctly. Though I am unsure why. I'll include both derived and base constructors, and the base copy as well.
Thanks for any assistance.
MATRIX (BASE) CONSTRUCTOR
Matrix::Matrix(int M, int N, double* input_data)
{
this->M = M;
this->N = N;
//cout << "Matrix Constructor\n";
data = new double[M*N];
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
data[i*N+j] = input_data[i*N+j];
}
}
delete [] input_data;
}
MATRIX (BASE) COPY CONSTRUCTOR
Matrix::Matrix(const Matrix& copy)
{
//cout << "Copy Constructor\n";
M = copy.M;
N = copy.N;
data = new double[M*N];
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
data[i*N+j] = copy.data[i*N+j];
}
}
}
BINARYMATRIX (DERIVED) CONSTRUCTOR
BinaryMatrix::BinaryMatrix(int M, int N, double* input_data) : Matrix(M, N, input_data)
{
data = new double[M*N];
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
this->data[i*N+j] = this->getRead(i, j);
}
}
double thr_val = this->Mean();
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
if (this->data[i*N+j] > thr_val)
this->data[i*N+j] = 1;
if (this->data[i*N+j] < thr_val)
this->data[i*N+j] = 0;
}
}
}

Why do you create a new copy of the matrix data in the BinaryMatrix copy constructor? The copy constructor of Matrix you call from the BinaryMatrix copy constructor already does this.
In the BinaryMatrix copy constructor you discard the copy of the matrix data the Matrix copy constructor already made (without deleteing it) and create a new one. This is a memory leak - the memory will be exhausted if you do that often enough.

If M and N are private to Matrix and BinaryMatrix derives from Matrix, I am not sure why your code compiles (you should not be able to access M, N in BinaryMatrix). If your declaration of BinaryMatrix also includes members M and N (as well as Matrix::N and Matrix::M) then this could be the source of the problem.
If BinaryMatrix does not declare M and N, then I think we still don't have enough data to diagnose your problem. To guess a bit, perhaps M*N does not fit into the type used for M. So you have an arithmetic overflow. The array size is specified in size_t, so a cast will work OK.
Also, you probably want to delegate the management of the data to exactly one of the classes. That is, do either this:
BinaryMatrix::BinaryMatrix(const BinaryMatrix& copy) : Matrix(copy)
{
// M, N, data already set in Matrix::Matrix(const Matrix&)
// The data has also been copied, so there is nothing to do here.
}
or this:
#include <algorithm>
BinaryMatrix::BinaryMatrix(const BinaryMatrix& copy)
: Matrix(), M(0), N(0),
data(0) // null in case new throws an exception (avoid bad delete in dtor).
{
const size_t nelems(size_t(copy.M)*size_t(copy.N));
data = new double[nelems];
M = copy.M;
N = copy.N;
stl::copy(copy.data, copy.data+nelems, data);
}
I think generally it is not a good idea to use int for iterating over dynamic data structures, since nothing guarantees that the actual size of the structure fits into int. That guarantee does exist however for size_t (any existing object must have a size representable in size_t, so you can iterate over any contiguous object using size_t).
In fact, I'm not really sure what distinction (of purpose or behaviour) you're trying to get from Matrix and BinaryMatrix. The data seems to have the same representation. If it is a difference of behaviour but not representation you are looking for, I think it might be better to use composition (that is, a separate un-inherited representation class) rather than inheritance. See What is the Liskov Substitution Principle? for an explanation of how to think usefully about when to use inheritance.
However, if none of the answers you have seen so far actually helps to solve your problem, you should put some time into cutting down your example: what is the smallest complete example program which demonstrates your problem? Post that.

If the error is that M and N are private. then you must change there protection level to protected or public or provide an access method that is. Vairables defined in a base class that are private are innacceassable to the derived classes.
class A
{
int x;
}
class B : public A
{
int DoSomething()
{
return x; //This is an error X is private to class A and as such inaccessible.
}
}

Related

Trying to copy a 2D dimensional array of objects to another function

I'm trying to copy an array from one class to to another class by passing it to a function but I'm running into issues. The array that I'm trying to copy seems to lose all its data.
// A.h
class A
public:
virtual void Test();
private:
A* array2D[30][32];
// A.cpp
void A::Test()
{
B* f = new B();
f->pass(array2D);
}
// B.h
class A;
class B
{
public:
void pass(A *a[][32]);
private:
A *a[30][32];
}
// B.cpp
void B::pass(A *array2D[][32])
{
for (int i = 0; i <= 30; i++)
{
for (int j = 0; j <= 32; j++)
{
a[i][j] = array2D[i][j];
}
}
}
My guess is that it's happening when I'm passing it but I'm not sure what I'm doing wrong.
My guess is that it's happening when I'm passing it but I'm not sure what I'm doing wrong.
First, your for loops to populate the array go out-of-bounds on the last iteration of the nested for loop:
void B::pass(A *array2D[][32])
{
for (int i = 0; i <= 30; i++) // This goes out-of-bounds on the last iteration
{
for (int j = 0; j <= 32; j++) // This also goes out-of-bounds.
{
a[i][j] = array2D[i][j];
}
}
}
Using <= in a for loop is an indication that things can go wrong, and they do go wrong with your code. The fix would simply be:
void B::pass(A *array2D[][32])
{
for (int i = 0; i < 30; i++)
{
for (int j = 0; j < 32; j++)
{
a[i][j] = array2D[i][j];
}
}
}
This will work, however it is inefficient (unless a great optimizing compiler sees that this is inefficient and changes the code).
The better way to do this is a simple call to std::copy:
#include <algorithm>
void B::pass(A *array2D[][32])
{
std::copy(&array2D[0][0], &array2D[29][32], &a[0][0]);
}
The reason why this works is that two-dimensional arrays in C++ have their data layout in contiguous memory, thus it is essentially a one-dimensional array. So giving the starting and ending address of the array elements is all that's required.
A compiler will more than likely see that you are copying a trivially-copyable type (a pointer), thus the call to std::copy results in a call to memcpy.

munmap_chunk(): invalid pointer in C++ program

I get an error "munmap_chunk(): invalid pointer", I don't know why. Problem appears when I use MultipliedByMatrix method. It can't properly delete the matrix that was created in this method.
#include "matrix.h"
Matrix::Matrix(int matr_size) {
size = matr_size;
Matr = new int *[size];
for(int i = 0; i < size; i++)
Matr[i] = new int[size];
for(int i = 0 ; i < size; i++)
for(int j = 0; j < size; j++)
Matr[i][j] = rand() % 100;
std::cout << "New matrix is created" << std::endl;
}
Matrix::~Matrix() {
for(int i = 0; i < size; i++)
delete[] Matr[i];
delete[] Matr;
Matr = NULL;
std::cout << "Matrix is deleted" << std::endl;
}
Matrix Matrix::MultipliedByMatrix(Matrix OtherMatr) {
Matrix new_matr = Matrix(this->GetSize());
int new_value;
for(int i = 0 ; i < size; i++)
for(int j = 0; j < size; j++) {
new_value = 0;
new_value += Matr[j][i] * OtherMatr.GetValue(i, j);
new_matr.SetValue(i, j, new_value);
}
return new_matr;
}
int Matrix::GetSize() {
return size;
}
int Matrix::GetValue(int i, int j) {
return Matr[i][j];
}
void Matrix::SetValue(int i, int j, int value) {
Matr[i][j] = value;
}
Did you write the Matrix class yourself? If so, I bet the problem is that you don't have a copy or move constructor. If so, the compiler will have generated one for you. This will copy the values of size and Matr but it won't create copies of the pointed-to arrays. When you write:
return new_matr;
this creates a new matrix (using the copy constructor - which just copies the pointer), and then calls the destructor of new_matr (which deletes the memory which is pointed to). The calling function is then dealing with junk memory, and when it tries to eventually delete the result, all hell will break loose
You also will need to write a move assignment operator.
Alternatively make Matr a std::vector<int> (of length 'size' squared), and write:
int Matrix::GetValue(int i, int j) {
return Matr[i*size+j];
}
(and similarly for other functions). std::vector has a proper copy and move constructor, and proper assignment behaviour - so it will all just work. (It will also be a lot faster - you save a whole pointer indirection.)
This is not an analytical answer to the question but a piece of advice with respect to solving (or better circumventing) the problem.
Avoid memory handling on your own if you can. (And it is very likely that you actually can avoid it.)
You can read my answer on the question "1D or 2D array, what's faster?" to get a lengthy explenation why it is probably undesirable to use the kind of memory layout you're using.
Furthermore, you'll find an (yet untested) example of how to implement a simple matrix container on top of std::vector.
You can look at the scheme and try to implement your own if you want. The design has several advantages compared to your implementation:
It is templated and thus usable with int as well as many other types.
Conformance to the standard container concept is achieved easily.
No destructor / copy constructor / move constructor or assignment operators required: std::vector is handling the resources and does the "dirty work" for you.
If you still want to use your RAW-Pointer approach (for academic purposes or something):
Read What is meant by Resource Acquisition is Initialization (RAII)? and try to understand the answers.
Read What is The Rule of Three? properly and make sure you have implemented (preferably obeying the RAII concept) those functions:
copy constructor,
destructor,
assignment operator and if desired
move constructor and
move assignment operator.
Still read my answer to the "1D or 2D array, what's faster?" question to see how you would want to organize your allocations in order to be exception safe in case of std::bad_alloc.
Example: Your constructor the 'a little better' way:
Matrix::Matrix(std::size_t const matr_size) // you have a size here, no sign required
{
Matr = new int*[matr_size];
std::size_t allocs(0U);
try
{ // try block doing further allocations
for (std::size_t i = 0; i < matr_size; ++i)
{
Matr[i] = new int[matr_size]; // allocate
++allocs; // advance counter if no exception occured
for(std::size_t j = 0; j < matr_size; j++)
{
Matr[i][j] = rand() % 100;
}
}
}
catch (std::bad_alloc & be)
{ // if an exception occurs we need to free out memory
for (size_t i = 0; i < allocs; ++i) delete[] Matr[i]; // free all alloced rows
delete[] Matr; // free Matr
throw; // rethrow bad_alloc
}
}

Overload operator to transpose array

I'm tryining overload operator ~ that transpose a given matrix:
Here's my code:
virtual B operator~()const
{
B a(column,row);
for (int i = 0; i<row; i++)
{
for (int j = 0; j<column; j++)
{
a.e[i] = e[j];
}
}
return a;
}
e is pointer to the memory storing all integer elements of B
int *const e;
But on the output I've gotten a matrix filled by zeros and with the same size. I mean if I wnat transpose 5x2, I got the same 5x2 filled by zeros.
Edit:
My constuctor:
B(int r, int c)
: row(r), column(c), e(new int[r*c])
{
for (int i = 0; i < r*c; i++)
{
e[i] = 0;
}
}
Your code is not filling a.e properly: rather than transposing the matrix, it keeps overriding a region that corresponds to the same row with numbers for different columns.
Assuming row-major order, the code should be like this:
for (int i = 0; i<row; i++)
{
for (int j = 0; j<column; j++)
{
a.e[j*row+i] = e[i*column+j];
}
}
Since you mention that you've got a result filled with zeros, the logic of your copy constructor and / or the assignment operator may not be coded correctly. Note that since B::e is allocated dynamically, you need a destructor as well.
B a(column,row);
for (int i = 0; i<row; i++)
{
for (int j = 0; j<column; j++)
{
a.e[i] = e[j];
}
}
Isn't accessing most of the elements in either this or a. Only element 0 to column and 0 to row respectively are accessed.
The zeroing constructor does not reveal how the row/columns are stored, but a guess would be
int& B::at(int r, int c){
return e[r*column + c];
}
The alternative is
return e[c*row + r];
In this case you can transpose by
virtual B operator~()const
{
B a(column,row);
for (int i = 0; i<row; i++)
{
for (int j = 0; j<column; j++)
{
a.at(i, j) = at(j, i); // swap row, column
}
}
return a;
}
First, you seem to always set the first [0..row] elements in the transpose, with the last elements on every row in the original and stop there.
Second, i don't know how B is internally laid, but because you can specify the size of the matrix, i deduce that the internal array that is used to store the elements is allocated dynamically in a one-dimension buffer. This means that you have a copy constructor to avoid problems with the deletion of a at the end of the method. You getting a lot of 0s possibly means (beside the fact that you don't scan the entire matrix), that your copy constructor is not properly implemented.
EDIT Seeing your edit of the question, i tend to be sure that the copy constructor is the problem. You don't have a crash because 5x2 = 2x5 elements (so the internal buffer is the same size).

C++ object construction in a multidimensional dynamic array

I am trying to create an nxn array of objects, but I do not know where to call their constructors. Here is my code:
class obj {
private: int x;
public: obj( int _x ) { x = _x; }
};
int main( int argc, const char* argv[] ) {
int n = 3; //matrix size
obj** matrix = new obj*[n];
for( int i = 0; i < n; i++ )
matrix[i] = new obj[n];
return 0;
}
If only the default constructor invocation is required, your code already calls it.
For a non-default constructor add a nested loop, like this:
for( int i = 0; i < n; i++ ) {
matrix[i] = new obj[n];
for (int j = 0 ; j != n ; j++) {
matrix[i][j] = obj(arg1, arg2, arg3); // Non-default constructor
}
}
A better approach is to use std::vector of obj if no polymorphic behavior is required, or of smart pointers to obj if you need polymorphic behavior.
If you really want to muck around with low-level memory management, then you can't - the array form of new doesn't allow you to pass arguments to the objects' constructors. The best you could do is to let them be default-constructed (adding a constructor to your class if necessary) and then loop through and reassign them. This is tedious and error-prone.
I'd suggest using higher-level classes; for dynamic arrays, use a vector:
std::vector<std::vector<obj>> matrix(n);
for (auto & row : matrix) {
row.reserve(n);
for (size_t i = 0; i < n; ++n) {
row.emplace_back(/* constructor argument(s) here */);
}
}
As a bonus, RAII means you don't need to delete all the allocations yourself, and it won't leak memory if any of this fails.
dasblinkenlight has already given quite a good answer, however, there is a second way to do it that's more efficient. Because, if you do (the code is taken from his answer)
matrix[i] = new obj[n];
for (int j = 0 ; j != n ; j++) {
matrix[i][j] = obj(arg1, arg2, arg3); // Non-default constructor
}
the following will happen:
Memory for n objects is allocated.
All n objects are default constructed.
For each object, a new object is custom constructed on the stack.
This object on the stack is copied into the allocated object.
The object on the stack is destructed.
Obviously much more than would have been necessary (albeit perfectly correct).
You can work around this by using placement new syntax:
matrix[i] = (obj*)new char[n*sizeof obj]; //Allocate only memory, do not construct!
for (int j = 0 ; j != n ; j++) {
new (&matrix[i][j]) obj(arg1, arg2, arg3); // Non-default constructor called directly on the object in the matrix.
}

Bad Access Error in 2D-Array (Matricies)

I have a little bit of a problem... I understand what a EXC_BAD_ACCESS error is and I generally know how to fix it but this one has got me completely stuffed. I have this all within a class, here is one method:
double Matrix::get_element(int r, int c) const {
//Retrieve the element at row r and column c
//Should not modify the value stored in Matrix but return a double copy of the value
double currentValue = matrix[r][c];
return currentValue;
}
Now, I have another piece of my code that calls this method:
std::string Matrix::to_string() const {
std::string result;
double current;
Matrix working = *this;
std::ostringstream oss;
oss << "[";
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
current = 0.0;
current = working.get_element(i, j);
oss << " " << current << " ";
}
oss << "; ";
}
oss << "]";
result = oss.str();
return result;
}
I know that the working object has 3 rows and 3 cols at the point where working.get_element(i, j); is called. The variable list shows me just before the get_element() method, that both rows and cols are set to 3. In the method, I'm able to get the value at get_element(0, 0) but not get_element(0, 1).
I can't see why this is the case... Anyone know why or require more of my code to understand why these methods are being called?
EDIT:
Here is the header file:
class Matrix {
private:
//Any variables required
int rows;
int cols;
double **matrix;
public:
Matrix(); //Working M
~Matrix(); //Working M
Matrix(int r, int c); //Working M
int getRows();
int getCols();
void set_element(int r, int c, double val); //Working M
double get_element(int r, int c) const; //Working M
void clear(); //Working M
bool is_empty(); //Working M
bool is_identity(); //Working M
const Matrix transpose(); //Working M
int minorMat(double **dest, const int row, const int col, int order); //Working M
double get_determinent(); //Working M
double higherDeterminents(int order); //Working M
const Matrix operator+(const Matrix &rhs); //Working M
const Matrix operator-(const Matrix &rhs); //Working M
const Matrix operator*(const Matrix &rhs);
bool operator==(const Matrix &rhs); //NOT assessed
const Matrix operator*(const double &rhs);
const Matrix operator/(const double &rhs);
Matrix & operator=(const Matrix &rhs);
std::string to_string() const;
};
Do ignore the comments sorry. And this is the constructors/destructors:
Matrix::Matrix() {
//Basic Constructor
rows = 1;
cols = 1;
matrix = new double*[rows];
for (int i = 0; i < rows; ++i) {
matrix[i] = new double[cols];
}
}
Matrix::~Matrix() {
//Basic Deconstructor
for (int i = 0; i < rows; ++i) {
delete[] matrix[i];
}
delete[] matrix;
rows = NULL;
cols = NULL;
matrix = NULL;
}
Matrix::Matrix(int r, int c) {
//Empty matrix (all 0's) with r rows and c columns, if they are -ve, set to 1
rows = r;
cols = c;
if (cols < 0)
cols = 1;
if (rows < 0)
rows = 1;
matrix = NULL;
matrix = new double*[rows];
for (int i = 0; i < rows; i++) {
matrix[i] = new double[cols];
}
}
EDIT2:
Matrix & Matrix::operator=(const Matrix &rhs) {
//rhs is matrix to be copied
//rhs compied into Matrix called on
double toCopy;
for (int i = 0; i < rhs.rows; i++) {
for (int j = 0; j < rhs.cols; j++) {
toCopy = rhs.get_element(i, j);
this->set_element(i, j, toCopy);
}
}
return *this;
}
It is impossible for us to say when you do not state how you declare and initialize the matrix element. Using something like that in your CTOR should be fine:
class Matrix {
float matrix[3][3];
...
}
Don't forget to initialize it in your CTOR to something that makes sense.
Btw: why do you do this: Matrix working = *this; ?? You could simply this->get_element(i, j); instead, which would not invoke copying of your whole object. [1]
EDIT: Update since you updated your answer. You should be careful with your copy CTORs and operator=() statements. It is easily possible to make double deletes or something ugly like that.
EDIT2: I think the problem is this line:
Matrix working = *this;
You are creating a new copy working of your this object. But working gets initialized with only 1 column and 1 row (as defined in your standard CTOR). I'm not sure if you are checking the bounds when calling set_element or get_element so I guess you are writing over the bounds of your arrays.
I think the best idea is to just remove the line Matrix working = *this; and to adhere to my tip in above:
this->get_element(i, j); in std::string Matrix::to_string() const.
Your Matrix(int r, int c) allocates memory for matrix, but leaves the values it points to uninitialized. Add something like this to the constructor:
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
this->set_element(i, j, 0);
}
}
Doing like this:
int main()
{
Matrix m(3,3);
std::cout << m.to_string();
}
Output:
[ 0 0 0; 0 0 0; 0 0 0; ].
Same thing in the default constructor:
Matrix::Matrix() {
//Basic Constructor
rows = 1;
cols = 1;
matrix = new double*[rows];
for (int i = 0; i < rows; ++i) {
matrix[i] = new double[cols];
}
}
You allocated memory, but wherever matrix[0][0] points to, it's uninitialized garbage value. Do something like matrix[0][0] = 0; or whatever default value you want it to have.
Hope that helps.
Your class is violating the "big three" rule. If a class has one of a destructor, assignment operator or copy constructor then it most probably you need to have all three.
In your case you have a destructor, but no assignment operator or copy constructor, and this is going to create an UB condition when you do Matrix working = *this.
By the way there are two other problems with your code
From the comment seems that you think that new double[size] will initialize the elements to 0 and this is not true.
Most of your code is technically very bad. Your matrix class would be much easier (less code) to implement correctly using std::vector instead of pointers and dynamic memory. Of course if this is just an exercise then it make sense to avoid using std::vector.
By the way if you never heard about the "big three" rule chances are that you're trying to learn C++ with experimentation instead that by reading.
With C++ this is not a smart move... logic can be used as substitute for study if 1) the topic is highly logical, 2) if you can be told when you get it wrong.
Instead C++ is very very complex and in a few place is also quite illogical (for historical reasons) so there are parts in which logic will simply misguide you.
Moreover when you make a mistake in C++ you don't get in general an error message, but "Undefined Behavior". This basically makes very very hard to learn C++ with experimentation because even wrong code may apparently work. It is also very easy to write code that looks good and that is instead quite wrong for subtle reasons.
Instead of just experimenting you should grab a good book and read it cover to cover...