Unable to fix a Access Violation reading location error - c++

So, I've looked around for an answer for a while, trying to solve this error. I think I know what the problem is, but I still can't find where or how it's happening exactly.
The error is that I'm getting a Access Violation at the location 0xcccccccc. My searching has lead me to that the problem is that I'm trying to delete a pointer that either doesn't exist, which I don't believe, or that I'm deleting a temporary variable. The problem is that I can't figure out which it is. I'm sure that once it's pointed out I'll feel stupid, but I REALLY can't seem to see this.
Pertinent Code down the callstack from the top.
// Minimum Polynomial Function
matrix matrix::MIN_POLY()
{
// Get stuff ready to find the Minimal Polynomial of the matrix
// Get our I matrix in.
col[0] = MatrixPow( *this, 0); // Goes in here <-
// ... Rest of the function ...
}
// Matrix Power Function
matrix matrix::MatrixPow(matrix& A, int pow)
{
// Create an identity matrix should the pow == 0
matrix ret(A.size[0], A.size[1]);
for(int i = 0; i < ret.size[0]; ++i)
{
ret.data[i][i] = 1;
}
for( int i = 0; i < pow; ++i)
{
// multiply it by the number of times given, and 0 returns I
ret = MatrixMult(ret, A);
}
// Ret.data exists here still and is ready to be moved and deleted.
return ret; // Seems to call Copy around here for some reason. <------
}
// Copy constructor
matrix::matrix(const matrix& other)
{
// Ret.data is gone by here for some reason.
if(data)
{
for(int i = 0; i < size[0]; ++i)
{
delete[] data[i]; // Error happens in one of these deletes <-----
}
delete[] data;
}
// Rest doesn't matter as it stops above
}
And the matrix.h since it was asked for.
#include <complex>
class matrix
{
private:
std::complex<float> **data; // [row][column]
int size[2]; // 0 is rows/ 1 is columns
public:
// Default Constructor
matrix();
// Default Destructor
~matrix();
// Default Copy
matrix(const matrix& other);
// Premade matrix constructor
matrix(int row, int col, std::complex<float>** mat);
// Assignment operator to get stuff done
matrix& operator=(const matrix& other);
// Set function for the matrix
void Set(int row, int col, std::complex<float> dat);
// Get function for the matrix, inline for ease.
std::complex<float> Get(int row, int col)
{return data[row][col];}
// Get function for the number of rows
int GetRows()
{return size[0];}
// Get function for the number of columns
int GetCol()
{return size[1];}
// Scalar Multiplication
void ScalarMult(std::complex<float> scalar);
// Matrix Multiplication
matrix MatrixMult(const matrix& A, const matrix& B);
// Matrix Power series
matrix MatrixPow(matrix& A, int pow);
// Matrix addition
matrix MatrixAdd(const matrix& lhs, const matrix& rhs);
// Row op addition
void RowOp(int row1, int row2, std::complex<float> val1, std::complex<float> val2);
// Row op Swap
void RowSwap(int row1, int row2);
// RREF function
void RREF();
// minimal Polynomial
matrix MIN_POLY();
};

You define copy constructor:
matrix::matrix(const matrix& other)
Do not initialize members:
matrix::matrix(const matrix& other)
{
//body...
}
And then perform such check:
if(data)
Which by all means cannot be false - all pointers all initialized to compiler-specific sentinel value to indicate uninitialized state and help detect bugs like this. This usually applies to debug builds, unless you enable this also in release builds.
Solution:
1. Initialize data:
matrix::matrix(const matrix& other)
: data(NULL)
{
//body...
}
2. Do not perform this unnecessary check:
matrix::matrix(const matrix& other)
: data(NULL)
{
// copy size
size[0] = other.size[0];
size[1] = other.size[1];
// Make the numbers match
data = new std::complex<float>*[size[0]];
for(int i = 0; i < size[0]; ++i)
{
data[i] = new std::complex<float>[size[1]];
for(int j = 0; j < size[1]; ++j)
{
data[i][j] = other.data[i][j];
}
}
return;
}

Related

C++ use of deleted function with unique_ptr, make_unique

A pseudo class performing matrix additon using std::unique_ptr as the data member to represent the elements. M-rows, N columns. Class is templated for type, M, N. I am trying to perform a matrix addition (C = A+B) and keep getting this error from "error: use of deleted function". I am trying to crunch the fundamentals of C++ with a complication of smart_ptrs, any pointers regarding this error is appreciated.
All the participating functions (in the error) are shown below:
class Matrix{
private:
std::unique_ptr<T[]> array=std::make_unique<T[]>(M*N);
public:
Matrix();
Matrix( const Matrix& other );
inline Matrix operator+( const Matrix& other ) const;
const Matrix& operator=( const Matrix< M, N, T >& other );
}
Matrix::Matrix(const Matrix& other)
{
*this = other;
}
inline Matrix
Matrix::operator+( const Matrix& other ) const
{
Matrix result(*this);
result += other;
return result;
}
const Matrix&
Matrix::operator=( const Matrix& other )
{
if(this != &other)
this->array = std::move(other.array);
return *this;
}
Error reporting places:
error: use of deleted function ‘matlib::Matrix<2ul, 2ul, double>::Matrix(const matlib::Matrix<2ul, 2ul, double>&)’
Matrix< M, N, T > result(*this);
error: use of deleted function ‘std::unique_ptr<_Tp [], _Dp>& std::unique_ptr<_Tp [], _Dp>::operator=(const std::unique_ptr<_Tp [], _Dp>&) [with _Tp = double; _Dp = std::default_delete<double []>]’
this->array = std::move(other.array);
Thanks in advance.
In general, most of your errors originate from that std::unique_ptr has no copy constructor. This is so that it can efficiently manage the scope of the pointer inside of it. One way around this is to create a new std::unique_ptr, and copy all individual values over.
I've written an example class for you, perhaps it can help.
#include <memory>
template <class T>
class Matrix
{
private:
std::unique_ptr<T[]> data = nullptr;
size_t height, width;
public:
Matrix(size_t h, size_t w)
: height(h), width(w)
{
if(h*w == 0) return;
data = std::make_unique<T[]>(h*w);
}
Matrix(const Matrix& other)
{
height = other.height;
width = other.width;
data = std::make_unique<T[]>(height * width);
for(size_t i = 0; i < height; i++)
{
for(size_t j = 0; j < width; j++)
{
(*this)(j, i) = other(j,i);
}
}
}
Matrix operator=( const Matrix& other )
{
if(this == &other)
{
return *this;
}
height = other.height;
width = other.width;
data.reset(std::make_unique<T[]>(other.height * other.width));
for(size_t i = 0; i < height; i++)
{
for(size_t j = 0; j < width; j++)
{
(*this)(j, i) = other(j,i);
}
}
return *this;
}
T & operator()(size_t x, size_t y)
{
//If data is nullptr then this is undefined behaviour.
//Consider adding a throw or assert here
return data[y * height + x];
}
T operator()(size_t x, size_t y) const
{
//If data is nullptr then this is undefined behaviour.
//Consider adding a throw or assert here
return data[y * height + x];
}
size_t getHeight() const
{
return height;
}
size_t getWidth() const
{
return width;
}
};
As a final statement, if what you want to do is to create matrices for mathematical purposes, I suggest you give them static sizes for performance reasons. Adding in mathematical operators to a class like this involves additional logic for the cases where dimensions are mismatched. Statically sized matrices will solve this by themselves due to their typing. You can still do it like this, but be wary of any edge cases.

Polynomial code

I'm working on an assignment for my C++ class and have run into a little problem when running the program. I get an error stating Unhandled exception at 0x000944C8 in Pog11.exe: 0xC0000005: Access violation writing location 0x00000000. while debugging. The goal is to read in the int degree of a polynomial, as well as the double coefficients.
here is the .h file that I was supplied:
#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H
#include<iostream>
using std::ostream;
using std::istream;
using std::cerr;
using std::endl;
class Polynomial
{
friend ostream& operator<<( ostream& left , const Polynomial& right);
friend istream& operator>>( istream& left , Polynomial& right );
public:
Polynomial();
Polynomial( int degree, const double* coefficients );
Polynomial( const Polynomial& );
~Polynomial();
const Polynomial& operator=( const Polynomial& deg);
bool operator==( const Polynomial& deg ) const;
void setDegree(int d);
int getDegree() const;
private:
int degree;
double* coefficients;
};
#endif
And here is the segment of code that is causing the error:
istream& operator>>(istream& left, Polynomial& right)
{
int tmp;
left >> tmp;
right.setDegree(tmp);
int i = 0;
while (i<=right.getDegree())
{
double co;
left >> co;
right.coefficients[i] = co;
i++;
}
return left;
}
Specifically the right.coefficients[i]=co; line is what causes the program to crash.
Here are the constructors for the class:
#include "Polynomial.h"
Polynomial::Polynomial() :degree(0), coefficients(0)
{
degree = 0;
coefficients = new double[degree];
}
Polynomial::Polynomial(int deg, const double* coefficients)
{
if (deg < 0)
{
degree = 0;
}
else
{
degree = deg;
}
coefficients = new double [degree];
}
Polynomial::Polynomial(const Polynomial& deg)
{
if (deg.getDegree() <= 0)
{
setDegree(0);
}
else
{
setDegree(deg.getDegree());
for (int i = 0; i < degree; i++)
{
coefficients[i] = deg.coefficients[i];
}
}
}
There's code missing - e.g. the implementation of the constructor of the Polynomial object.
I'm pretty sure that your error is that you have not allocated (enough) memory for the coefficients data member. There must be a
coefficients = new double[number_of_coeffs]
somewhere in your code.
EDIT
There's a number of points where you need to do this: where the degree of the polynomial is (re)set. Because then you know the degree of the polynomial:
Here you must copy the elements passed:
Polynomial( int degree, const double* coefficients ):
coefficients( new double[degree] ), degree( degree )
{
::memcpy(this->coefficients, coefficients, degree * sizeof(double));
}
and in this one, the degree of the polynomial changes - so your coefficients array must be modified accordingly.
Polynomial::setDegree( int degree ) {
// first delete the old coefficients
delete [] coeffs;
// and make a new array
this->degree = degree;
this->coefficients = new double[ this->degree ];
// initialize the coefficients
..
}
Similar actions have to be done in the copy constructor and the assignment operator.
Finally: you might be better off using std::vector<double> which basically does all the memory management for you. See http://en.cppreference.com/w/cpp/container/vector

Segmentation fault when creating a row-major array

I'm trying to implement a row-major array, which is basically a single dimension representation of a 2D array.
This is my class definition
class RMA{
public:
RMA(){
size_=0;
row_=0;
column_=0;
arr_ = new double[size_];
}
RMA(int n, int m){
size_ = n*m;
column_ = m;
row_ = n;
if(size_== 0) arr_ = 0;
else arr_ = new double[size_];
}
RMA(const RMA& arr) {
size_ = arr.size_;
if(this != &arr){
delete [] arr_;
arr_ = new double[size_];
for(int i=0; i<size_; i++){
arr_[i] = arr.arr_[i];
}
}
return *this;
}
const double& operator() (int n, int m) const{
return arr_[n*column_+m];
}
double& operator()(int n, int m){
return arr_[n*column_+m];
}
~RMA(){delete[] arr_ ;}
private:
int size_;
int column_;
int row_;
double* arr_;
}
I've a calling function which creates the array.
RMA create_array() {
RMA arr;
arr = RMA(N, M);
std::cout<<"success";
return arr;
}
And this is my client
int main(int argc, char* argv[]) {
RMA arr = create_array();
return 0;
}
I end up getting segmentation fault. What am I doing wrong.
You use operations, that instead of cloning array, take a shallow copy of an object, and when destructors are used, they try to release the same memory block.
Implement the following operations:
RMA::RMA(const RMA&); // copy constructor - clone buffer
RMA& operator=(const &RMA); // assignment - clone buffer, release old
Also instead of:
RMA rma;
rma = RMA(a,b);
Use:
RMA rma = RMA(a,b) or RMA rma(a,b);
Edit: constructor code:
RMA::RMA(const RMA &rma) : size_(0), row_(0), column_(0), buffer_(0)
{
*this = rma;
}
RMA &operator=(const RMA&rma)
{
double *old = buffer_;
size_ = rma.size_;
row_ = rma.row_;
column_ = rma.column_;
buffer_ = new double[size_];
memcpy(buffer_, rma.buffer_, sizeof(buffer_[0]) * size_);
delete []old;
return *this;
}
The best solution is to get rid of all the new/delete, copy-constructors, and fluff. Use a private member variable to manage the memory, and follow the Rule of Zero. Like this:
struct RMA
{
RMA(size_t r = 0, size_t c = 0)
: row(r), column(c), arr(r * c) {}
const double& operator() (int n, int m) const
{ return arr[n * column + m]; }
double& operator() (int n, int m)
{ return arr[n * column + m]; }
private:
std::vector<double> arr;
size_t row, column;
};
That's it. You should not write any copy-constructor, assignment operator, move whatever, because the default-generated ones already do the right thing.
NB. row is actually redundant in my example too, you could remove it and calculate it when needed as arr.size() / column.
You could use .at( ) instead of [ ] on vector in order to throw an exception for out-of-bounds access, instead of causing undefined behaviour.

Efficent Sum and Assignment operator overloading in C++

Hi I'm implementing a matrix class in c++
I know that there are great libraries that do that like opencv but I need to do that myself.
For example if I implement the sum I can do like this
class Mat{
public:
double* data;
int rows,cols;
Mat(int r,int c):rows(r),cols(c){
data = new double[r*c];
}
};
void Sum(Mat& A,Mat& B,Mat& C){
for (int i = 0; i < A.rows*A.cols; ++i){
C.data[i] = A.data[i]+B.data[i];
}
}
int main(){
//Allocate Matrices
Mat A(300,300);
Mat B(300,300);
Mat C(300,300);
//do the sum
sum(A,B,C);
}
I would like to get something more readable like this but without losing efficiency
C = A + B
This way C is reallocated every time and I don't want that
Thank you for your time
Delay the calculation.
class MatAccess {
friend class Mat;
friend class MatOpAdd;
virtual double operator[](int index) const = 0;
};
class MatOpAdd: public MatAccess {
friend class Mat;
private:
const MatAccess& left;
const MatAccess& right;
MatOpAdd(const MatAccess& left, const MatAccess& right):
left(left), right(right) {}
double operator[](int index) const {
return left[index] + right[index];
}
};
class Mat: public MatAccess{
public:
double* data;
int rows,cols;
Mat(int r,int c):rows(r),cols(c){
data = new double[r*c];
}
MatOpAdd operator +(const MatAccess& other) {
return MatOpAdd(*this, other);
}
const Mat& operator = (const MatAccess& other) {
for(int i = 0; i < rows*cols; ++i) {
data[i] = other[i];
}
return *this;
}
private:
double operator[](int index) const {
return data[index];
}
double& operator[](int index) {
return data[index];
}
};
int main(){
//Allocate Matrices
Mat A(300,300);
Mat B(300,300);
Mat C(300,300);
//do the sum
C = A + B;
}
Now the '+' calculation will be done in the "operator="
Things I would change:
MatAccess should include the dimensions (rows,cols).
Mat adding constructors and operator= or make it not copyable
Mat::operator+ and Mat::operator= check for equal rows,col
delete memory when not used anymore or
use std::vector for simpler memory managment.
Created a bigger example here: https://gist.github.com/KoKuToru/1d23af4bbf0b2bc89893

Implementing a int stack in C++

I came across a exercise on the web, this is the text:
Write a class int_stack that will manage a stack of integers. The
integers values will be stored in a dynamically allocated array.
This class will propose the following member functions :
int_stack (int n) constructor that will dynamically allocate n
integers,
int_stack ( ) constructor allocating 20 integers,
~ int_stack ( ) destructor,
int empty ( ) the return value is 1 if the stack is empty, 0
otherwise,
int full ( ) the return value is 1 if the stack is full, 0 otherwise,
void operator < (int p) pushes (add) the p value on the stack,
int operator >(int p) returns (and remove) the value on the top of
the stack
I've tried to implement it, but the > (pull) operator won't work.
Here's my code:
int_stack.h
class int_stack
{
private:
int* stack;
unsigned int n, p;
void init(unsigned int n);
public:
int_stack(unsigned int n);
int_stack();
~int_stack();
int empty();
int full();
void operator <(int i);
int operator >(int i);
};
int_stack.cpp
#include "int_stack.h"
void int_stack::init(unsigned int n)
{
this->stack = new int[n];
this->p = 0;
}
int_stack::int_stack(unsigned int n)
{
this->init(n);
}
int_stack::int_stack()
{
this->init(20);
}
int_stack::~int_stack()
{
delete this->stack;
}
int int_stack::empty()
{
return (this->p == 0 ? 1 : 0);
}
int int_stack::full()
{
return (this->p == n-1 ? 1 : 0);
}
void int_stack::operator <(int i)
{
if (!this->full())
this->stack[p++] = i;
}
int int_stack::operator >(int i)
{
if(!this->empty())
return this->stack[p--];
return 0;
}
What am I doing wrong?
In addition to getting the indexing right, the class needs a copy constructor and an assignment operator. As written you'll get multiple deletes of the same data block:
int_stack s0;
int_stack s1(s0); // uh-oh
Both destructors will delete the array allocated by the constructor for s0.
There are several major flaws with you code:
Unless you want to resize the stack every time you push or pop something onto or off of it, respectively, you probably want to use a linked-list- or deque- style storage structure instead of a vector/array-style.
Overloading operator< and operator> to do what amounts to extraction and insertion is a terrible interface choice. I would urge against using operators for those operations:
void int_stack::push(int i)
{
// push an element onto the stack
}
int int_stack::pop()
{
// pop an element off of the stack
}
Because you are not implementing it as a linked-list or deque, when you go to push elements, you can (and eventually will) attempt to write outside the bounds of the memory you allocated.
Finally, you do not delete your stack properly. If you use new [], you must also use delete [].
The choice of interface is quite bad, but ignoring that fact consider what your members mean, in particular p. The index p refers to the location above the last added element. When you return the value in the pop operation you are reading the value from that location, but that location does not have a value:
int int_stack::operator >(int i)
{
if(!this->empty())
return this->stack[p--]; // <-- predecrement!
return 0;
}
Regarding the interface, operator< and operator> are unnatural choices for the push and pop operations. When someone reads in code s < 5 they interpret that you are comparing s with 5, not inserting an element into the stack s. That is going to be the source of confusion.
Worse than operator< is operator> defined as int operator>(int). User code to read a value will end up looking as:
value = s > 5;
That looks like comparing s to 5, and storing the result into value. Moreover, the actual behavior is completely independent on the argument 5, the same operation can be spelled as s > -1 or even s > 5.3
Here is the working implementation I came up with.
It implements a copy constructor and the assignment operator.
Also, the indexing works, and the interface has changed from the < and > operators to two simple push(int) and int pop() functions.
It throws exceptions when you try to push/pop over the boundaries.
int_stack.h
#include <exception>
class int_stack
{
private:
int* stack;
unsigned int n, p;
void init(unsigned int n);
void copy(int_stack& other);
public:
int_stack(unsigned int n);
int_stack();
int_stack(int_stack& other);
int_stack& operator=(int_stack& other);
~int_stack();
int empty();
int full();
void push(int i);
int pop();
class OutOfBoundariesException: public std::exception {};
};
int_stack.cpp
#include "int_stack.h"
void int_stack::init(unsigned int _n)
{
n = _n;
stack = new int[n];
p = 0;
}
int_stack::int_stack(unsigned int n)
{
init(n);
}
int_stack::int_stack()
{
init(20);
}
int_stack::int_stack(int_stack& other)
{
copy(other);
}
int_stack& int_stack::operator=(int_stack& other)
{
copy(other);
return *this;
}
void int_stack::copy(int_stack& other)
{
n = other.n;
p = other.p;
stack = new int[n];
for (unsigned int i = 0; i < n; i++)
stack[i] = other.stack[i];
}
int_stack::~int_stack()
{
delete[] stack;
}
int int_stack::empty()
{
return (p == 0 ? 1 : 0);
}
int int_stack::full()
{
return (p == n ? 1 : 0);
}
void int_stack::push(int i)
{
if (!full())
stack[(++p)-1] = i;
else
throw new OutOfBoundariesException;
}
int int_stack::pop()
{
if (!empty())
return stack[(p--)-1];
else
throw new OutOfBoundariesException;
return 0;
}