munmap_chunk(): invalid pointer in C++ program - c++

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

Related

Access violation when using delete[] on a 2-dim array [duplicate]

This question already has answers here:
What is The Rule of Three?
(8 answers)
Closed 2 years ago.
I'm doing a matrix-product exercise (strassen's algorithm actually) using C++. Since the biggest data set given reaches 2048 * 2048, I tried to free the temp memory using delete[]. But it says there is a memory access violation in it, why?
Here are some of the code that may help:
struct Matrix {
int row, column;
int** m;
Matrix(int row, int column) {
m = new int* [2048];
for (int i = 0; i < row; i++)
m[i] = new int[2048];
}
~Matrix() {
if (m != NULL) {
for (int i = 0; i < 2048; i++) {
delete[] m[i]; //access violation happens here
}
delete[] m;
}
}
};
Matrix matAdd(Matrix matA, Matrix matB) {
Matrix matR = Matrix(matA.row, matA.column);
for (int i = 0; i < matA.row; i++)
for (int j = 0; j < matA.column; j++) {
matR.m[i][j] = matA.m[i][j] + matB.m[i][j];
}
return matR;
}
//There are some other functions below but the structure is basically the same
The pointers in the array, starting from the index row were not initialized.
Matrix(int row, int column) {
m = new int* [2048];
for (int i = 0; i < row; i++)
m[i] = new int[2048];
// Initialize rest elements with null pointer.
for (int i = row; i < 2048; i++)
m[i] = nullptr;
}
The rest initialization will fix the crash, but then you will get crash on double free. The reason: you use copies of your class, thus you need to implement the copy constructor and the assignment operator or use shared pointers instead of raw pointers. The default copy makes pointers pointing to the same allocated objects.
Also look at the answer https://stackoverflow.com/a/1403180/6752050 with the example how to create a 2d matrix with a single allocation.
You should consider using std::vector<std::vector<int>>.
Your class is lacking copy constructor and copy assignment and I am certain it is a case of double free.

Program crashes at: (1) matrix multiplication; and (2) failed matrix addition/subtraction

In short, I was assigned the task of creating a class that dynamically allocates memory to form a matrix of int values.
Part of the class are member functions that perform the basic matrix calculations -- addition, subtraction, and multiplication. Everything compiles (on my end at least), but when I used a driver to test the multiplication portion, it keeps crashing.
I'm using Codeblocks as my IDE and haven't had much luck with the debugger there in trying to figure it out. It appears that the calculation completes (with correct values), but then things go horribly wrong somewhere.
For clarity, each object of the Matrix class has the following member data:
private:
int rows;
int cols;
int **element;
Below is a snippet of the implementation file in which the overloaded operator* is fleshed out. The portion where temp.element[i][x] is set to '0' before the loop performing the multiplication is commented out because the default constructor already sets all values to '0' -- which I had forgotten when I put it in originally. It didn't work when I didn't have it commented out either.
In testing, I used one 2x3 array and one 3x2 array.
Matrix Matrix::operator*(const Matrix &aMatrix) const
{
if(cols == aMatrix.rows)
{
Matrix temp(rows, aMatrix.cols);
for(int i = 0; i < rows; i++)
{
for(int x = 0; x < aMatrix.cols; x++)
{
//temp.element[i][x] = 0;
for(int n = 0; n < cols; n++)
{
temp.element[i][x] += (element[i][n]
* aMatrix.element[n][x]);
}
}
}
return temp;
}
else
{
cerr << "Matrix multiplication failed -- incompatible matrix sizes."
<< endl;
return *this;
}
}
Upon trying to go through the code and find errors, I started re-checking the other functions I had. It appeared that both addition and subtraction worked, but the program would close if the matrices were incompatible (ie. trying to add a 2x3 and a 4x4).
Below is the snippet for the addition (subtraction is almost identical just '-' instead of '+' in the final loops.
Matrix Matrix::operator+(const Matrix &aMatrix) const
{
if(rows == aMatrix.rows && cols == aMatrix.cols)
{
Matrix temp(rows, cols);
for(int i = 0; i < rows; i++)
{
for(int x = 0; x < cols; x++)
{
temp.element[i][x] = element[i][x] + aMatrix.element[i][x];
}
}
return temp;
}
else
{
cerr << "Undefined matrix addition -- matrices are different sizes."
<< endl;
return *this;
}
}
Any help or insight is appreciated. Thanks.
EDITED: Added overloaded assignment operator, copy constructor, and destructor code.
Below is the overloaded assignment operator:
Matrix Matrix::operator=(Matrix aMatrix)
{
if(this != &aMatrix)
{
for(int i = 0; i < rows; i++)
{
delete [] element[i];
element[i] = NULL;
}
delete [] element;
rows = aMatrix.rows;
cols = aMatrix.cols;
element = new int* [rows];
for(int i = 0; i < rows; i++)
{
element[i] = new int [cols];
for (int x = 0; x < cols; x++)
{
element[i][x] = aMatrix.element[i][x];
}
}
}
return *this;
}
Below is the copy constructor:
Matrix::Matrix(const Matrix &aMatrix)
{
rows = aMatrix.rows;
cols = aMatrix.cols;
element = new int* [rows];
for(int i = 0; i < rows; i++)
{
element[i] = new int [cols];
for (int x = 0; x < cols; x++)
{
element[i][x] = aMatrix.element[i][x];
}
}
}
Destructor:
Matrix::~Matrix()
{
for(int i = 0; i < rows; i++)
{
delete [] element[i];
element[i] = NULL:
}
delete [] element;
element = NULL;
}
You posted a copy constructor and assignment operator. Your assignment operator has 4 major issues:
You should pass the parameter by const reference, not by value.
You should return a reference to the current object, not a brand new object.
If new throws an exception during assignment, you've messed up your object by deleting the memory beforehand.
It is redundant. The same code appears in your copy constructor.
You can rewrite the assignment operator in terms of the copy constructor and alleviate these issues:
#include <algorithm>
//...
Matrix& Matrix::operator=(const Matrix& aMatrix)
{
Matrix temp(aMatrix);
swap(*this, temp);
return *this;
}
void Matrix::swap(Matrix& left, Matrix& right)
{
std::swap(left.rows, right.rows);
std::swap(left.cols, right.cols);
std::swap(left.element, right.element);
}
You just need to add the swap function to your Matrix class (probably as a private) function.
The code above uses the copy/swap idiom, and alleviates all of the issues I mentioned. This will work provided that your copy constructor and destructor are written properly. There are many threads on SO that talk about this idiom, but basically what is happening is this:
Create a temporary object from the passed-in object. If there is a problem with new throwing, your this doesn't get messed up.
Swap out this's members with the temporaries members. This refreshes the this object with the temporary's data, and gives the temporary the old data we don't need any more.
Let the temporary die with the old stuff we gave it from this.
Return this.
As to the other aspects, if the two Matrices cannot be multiplied, then just throw an exception. Do not return a bogus or confusing Matrix object that doesn't really reflect what happened.
In addition, you should first write operator += and *=. Why? Because implementing operator + and * can be done in terms of += and *=, respectively, plus you get the added bonus of having += and *= available.
For example:
Matrix& Matrix::operator+=(const Matrix &aMatrix)
{
if(rows != aMatrix.rows || cols != aMatrix.cols)
throw SomeException;
for(int i = 0; i < rows; i++)
{
for(int x = 0; x < cols; x++)
element[i][x] += aMatrix.element[i][x];
}
return *this;
}
Matrix Matrix::operator+(const Matrix &aMatrix)
{
Matrix temp(*this);
temp += aMatrix;
return temp;
}
So if the Matrix sizes are an issue, operator + and += will throw an exception. Note how operator + is implemented in terms of +=. Take the same approach to *, *=, and also - and -=.
You need to figure out what the syntax and semantics are of these operations. It looks from your example as though you want something like:
Matrix lhs = <something>;
Matrix rhs = <something>;
Matrix result = lhs * rhs;
to "just work". While this might be nice syntactically, you need to account for what happens if lhs and rhs can't be multiplied (or added, etc.) You also need to worry about setting up the result properly. You can't just return a "struct consisting of number of rows, columns and an array of pointers" and expect not to run into horrific memory management problems.
What will be responsible for making the product disappear? When it goes out of scope? C++ is not a very good language for linear algebra.
The first decision that you need to make is whether you intend to throw an exception for invalid operations, or return some indication of what went wrong, perhaps bool and a const char * to an error message.
Then you probably should try writing a function taking a result reference and 2 operand references, and just get the basic algebra right, if the matrices support the operation. (I have not mentioned yet that your Matrix is an integer matrix only.)
In "real life", you would probably try to find an open source standard solution that manages all of this, because numerical operations need to be managed very carefully.
One might even go so far as to suggest that this is a problem that has already been capably solved decades ago in Fortran, and to this day, if performance is an issue, there is a good chance that the underlying calculations might be in Fortran, or a library that was a port from C.

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

Allocate multidimensional array using new

When I allocate multidimensional arrays using new, I am doing it this way:
void manipulateArray(unsigned nrows, unsigned ncols[])
{
typedef Fred* FredPtr;
FredPtr* matrix = new FredPtr[nrows];
for (unsigned i = 0; i < nrows; ++i)
matrix[i] = new Fred[ ncols[i] ];
}
where ncols[] contains the length for each element in matrix, and nrows the number of element in matrix.
If I want to populate matrix, I then have
for (unsigned i = 0; i < nrows; ++i) {
for (unsigned j = 0; j < ncols[i]; ++j) {
someFunction( matrix[i][j] );
But I am reading C++ FAQ, who is telling be to be very careful. I should initialize each row with NULL first. Then, I should trycatch the allocation for rows. I really do not understand why all this. I have always (but I am in the beginning) initialized in C style with the above code.
FAQ wants me to do this
void manipulateArray(unsigned nrows, unsigned ncols[])
{
typedef Fred* FredPtr;
FredPtr* matrix = new FredPtr[nrows];
for (unsigned i = 0; i < nrows; ++i)
matrix[i] = NULL;
try {
for (unsigned i = 0; i < nrows; ++i)
matrix[i] = new Fred[ ncols[i] ];
for (unsigned i = 0; i < nrows; ++i) {
for (unsigned j = 0; j < ncols[i]; ++j) {
someFunction( matrix[i][j] );
}
}
}
catch (...) {
for (unsigned i = nrows; i > 0; --i)
delete[] matrix[i-1];
delete[] matrix;
throw; // Re-throw the current exception
}
}
1/ Is it farfetched or very proper to always initialize so cautiously ?
2/ Are they proceeding this way because they are dealing with non built-in types? Would code be the same (with same level of cautiousness) with double* matrix = new double[nrows]; ?
Thanks
EDIT
Part of the answer is in next item in FAQ
The reason for being this careful is that you'll have memory leaks if any of those allocations fail, or if the Fred constructor throws. If you were to catch the exception higher up the callstack, you have no handles to the memory you allocated, which is a leak.
1) It's correct, but generally if you're going to this much trouble to protect against memory leaks, you'd prefer to use std::vector and std::shared_ptr (and so on) to manage memory for you.
2) It's the same for built-in types, though at least then the only exception that will be thrown is std::bad_alloc if the allocation fails.
I would think that it depends on the target platform and the requirements to your system. If safety is a high priority and / or if you can run out of memory, then no, this is not farfetched. However, if you are not concerned too much with safety and you know that the users of your system will have ample free memory, then I would not do this either.
It does not depend on whether builtin-types are used or not. The FAQ solution is nulling the pointers to the rows so that in the event of an exception, only those rows which have already been created are deleted (and not some random memory location).
That said, I can only second R. Martinho Ferndandes' comment that you should use STL containers for this. Managing your own memory is tedious and dangerous.

Invalid Allocation Size (in derived class copy constructor)

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