Deleting a doublepointer (matrix) - c++

I am solving a quantum-mech problem which requires me to find some eigenvalues by manipulating some matrices. The specifics of this problem is not relevant, I just need help with the c++ problem, I am new to this language and after a couple of hours I figured any more attempts at solving it myself would be futile and so I turn to you for help.
I have this problem where glibc detects an error at the end of my program and I cannot deallocate properly, it is far too big to copypaste here so I will just replicate the part that actually gives the error.
void hamiltonian(int, double **&);
int i,j;
int main()
{
int N = 1000; double **A;
hamiltonian(N, A);
//Physics here
.
.
.
.
.
//Delete
for(i=0; i<N; i++){delete []A[i];}
delete []A;
return 0;
}
void hamiltonian(int N, double **&A)
{
A = new double *[N];
for(i=0; i<N; i++)
{
A[i] = new double[N];
for(j=0; j<N; j++)
{
if(i==j)A[i][j] = 2;
if(i==j+1 || i==j-1){A[i][j] = 1;}
}
}
}
According to my professor I have to deallocate in the same function as I allocate but I didn't even think about deallocation after being nearly done with my project and so I have to rewrite a lot of code, the problem is that I cannot deallocate A inside the hamiltonian function as I need it in other functions (inside //Physics).
Surely there must be a way around this? Might sound a bit ignorant of me but this sounds like a less efficient design if I have to deallocate in the same function as I allocate.

According to my professor I have to deallocate in the same function as I allocate
That is pure silliness. Sometimes (almost always) you need to use the allocated struct outside the function. Definitely false for objects, since constructors and destructors are different functions.
Any way, you can get away without using classes, if you make a Matrix struct and associated newMatrix and deleteMatrix functions :)
#include <cstddef>
#include <iostream>
using namespace std;
struct Matrix
{
int n;
int m;
double** v;
};
Matrix newMatrix (int n, int m)
{
Matrix A;
A.n = n;
A.m = m;
A.v = new double*[n];
for( int i = 0; i < n; i++ ){
A.v[i] = new double[m];
}
return A;
}
Matrix newHamiltonianMatrix (int n, int m)
{
Matrix A = newMatrix(n, m);
for( int i = 0; i < A.n; i++ ){
for( int j = 0; j < A.m; j++ ){
A.v[i][j] = 0.0;
if( i == j ){
A.v[i][j] = 2.0;
}
if( i == j + 1 or i == j - 1 ){
A.v[i][j] = 1.0;
}
}
}
return A;
}
void deleteMatrix (Matrix A)
{
for( int i = 0; i < A.n; i++ ){
delete [] A.v[i];
}
delete [] A.v;
A.v = NULL;
}
int main ()
{
Matrix A = newHamiltonianMatrix(10, 20);
for( int i = 0; i < A.n; i++ ){
for( int j = 0; j < A.m; j++ ){
cout << A.v[i][j] << " ";
}
cout << endl;
}
deleteMatrix(A);
}

delete A;
Needs to be
delete[] A;
If you new[] it, you MUST delete[] it. Also, use a vector- they take care of themselves.
vector<vector<double>> matrix;

There are couple of problems with your code.
(1) You are not allocating memory to the pointer members of A. i.e. A[i] are not allocated with new[]. So accessing them is an undefined behavior.
(2) You must do delete[] for a pointer if it was allocated with new[]. In your other function delete A; is wrong. Use delete[] A;
(3) Using new/new[] is not the only way of allocation. In fact you should use such dynamic allocation when there is no choice left. From your code it seems that you are hard coding N=1000. So it's better to use an 2D array.
const int N = 1000; // globally visible
int main ()
{
double A[N][N];
...
}
void hamiltonian (double (&A)[N][N])
{
...
}

Related

c++ Dynamic Allocation of 2D Array Class

Very new beginner here and I'm at the end of my rope with this assignment and would really appreciate any help :). Apologies in advance for the length.
I'm having some trouble with retrieving and setting values for my dynamically allocated 2D array. I have a class, defined below, that should construct a 2D array, at which point I need the option to set a value to a given point in the array and also to retrieve a value at a given point.
I ran the debugger, and got as far as to figure out that I have a segmentation fault when the setValue function runs. Can anyone help me understand what I'm doing wrong? As a beginner, the easier terms the better :). Thank you kindly in advance.
#include <iostream>
using namespace std;
class array2D
{
protected:
int xRes;
int yRes;
float ** xtable;
public:
array2D (int xResolution, int yResolution);
~array2D() {}
void getSize(int &xResolution, int &yResolution);
void setValue(int x,int y,float val);
float getValue(int x,int y);
};
array2D::array2D(int xResolution, int yResolution)
{
xRes=xResolution;
yRes=yResolution;
float ** xtable = new float*[yResolution];
for(int i=0;i < yResolution;i++)
{
xtable[i] = new float[xResolution];
}
for(int i=0;i < yRes;i++)
{
for(int j=0;j < xRes;j++)
{
xtable[i][j]=45;
}
}
}
void array2D::getSize(int &xResolution, int &yResolution)
{
xResolution=xRes;
yResolution=yRes;
cout << "Size of Array: " << xResolution << ", " << yResolution << endl;
}
void array2D::setValue(int x,int y,float val)
{
xtable[x][y] = val;
}
float array2D::getValue(int x,int y)
{
return xtable[x][y];
}
int main()
{
array2D *a = new array2D(320,240);
int xRes, yRes;
a->getSize(xRes,yRes);
for(int i=0;i < yRes;i++)
{
for(int j=0;j < xRes;j++)
{
a->setValue(i,j,100.0);
}
}
for(int i=0;i < yRes;i++)
{
for(int j=0;j < xRes;j++)
{
cout << a->getValue(i,j) << " ";
}
cout << endl;
}
delete[] a;
}
The line
float ** xtable = new float*[yResolution];
creates a function local variable. The member variable of the class still remains uninitialized. That's not what you want. To allocate memory and assign it to the member variable, remove the type specifier from that line. Just use:
xtable = new float*[yResolution];
Also, you need to switch the use of yResolution and xResolution in those lines. Otherwise, getValue and setValue will be using the indices incorrectly.
Swap the use of xResolution and yResolution in the following lines so that you use:
float ** xtable = new float*[xResolution];
for(int i=0;i < xResolution;i++)
{
xtable[i] = new float[yResolution];
}
Swap the use of xRes and yRes in the following lines so that you use:
for(int i=0;i < xRes;i++)
{
for(int j=0;j < yRes;j++)
{
xtable[i][j]=45;
}
}
Since your class acquires resources using dynamic memory allocation, you should read up on The Rule of Three and update your class accordingly.
int r,c;
cin>>r>>c;
int** p=new int*[r];
for(int i=0;i<r;i++) {
p[i]=new int[c];
}
for(int i=0;i<r;i++) {
delete [] p[i];
}
delete [] p;
Using this code you can create a 2D Dynamic Array in C++ which would allocate the memory of this array in the Heap Memory.

Two-dimensional dynamic allocated arrays created inside a class in C++ [duplicate]

This question already has answers here:
What is The Rule of Three?
(8 answers)
Closed 7 years ago.
I'm relatively new at c++ and other object oriented languages as a whole (have done one semester of C classes and now I'm having c++ classes). I'm having problems concerning the making of a dynamically allocated two-dimensional array through a class with a classmate.
The exercise itself would be:
Prepare a class named "matrix" capable of storing two-dimensional
arrays dynamically allocated (for float variables). Remember that
information such as height and width have to be properly stored
somewhere, element pointers too.
The class needs to contain constructors that allow the creation of
objects using one of the following strategies: The creation of an
array consisting of MxN elements, example:
Array A (4, 5);
The creation of an empty array:
Array B;
The creation of an array that is a copy of another previous one:
Array C (A);
After some time trying to figure out why it wasn't working properly, our code is currently this:
obs: "Matriz" is how we call a two-dimensional array in our language.
Matriz.h
#pragma once
class Matriz{
public:
int l, c;
float** matriz;
void setL(int _l);
void setC(int _c);
int getL();
int getC();
Matriz();
Matriz(int _l, int _c);
Matriz(Matriz& m);
float **getMatriz();
float getElement(int pL, int pC);
void setElement(int pL, int pC, float value);
};
Matriz.cpp
#include "Matriz.h"
Matriz::Matriz(){
l = c = 0;
matriz = new float*[l];
for (int i = 0; i<l; i++) {
matriz[l] = new float[c];
}
}
Matriz::Matriz(Matriz& m){
l = m.getL();
c = m.getC();
matriz = new float*[l];
for (int i = 0; i<l; i++) {
matriz[l] = new float[c];
}
for (int i = 0; i<l; i++) {
for (int j = 0; j<l; j++) {
matriz[i][j] = m.matriz[i][j];
}
}
}
Matriz::Matriz(int _l, int _c){
l = _l;
c = _c;
matriz = new float*[l];
for (int i = 0; i<l; i++) {
matriz[l] = new float[c];
}
}
float **Matriz::getMatriz(){
return matriz;
}
int Matriz::getC(){
return c;
}
int Matriz::getL(){
return l;
}
void Matriz::setC(int _c){
c = _c;
}
void Matriz::setL(int _l){
l = _l;
}
float Matriz::getElement(int pL, int pC){
return matriz[pL][pC];
}
void Matriz::setElement(int pL, int pC, float value){
matriz[pL][pC] = value;
}
main.cpp
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
int l = 2, c = 2;
float **m;
m = new float*[l];
for (int i=0; i<2; i++) {
m[i] = new float[c];
}
Matriz a(2, 2);
a.setC(2);
a.setL(2);
cout << " c = " << a.getC() << " l= " << a.getL() << "\n";
for (int i = 0; i<l; i++) {
for (int j = 0; j<c; j++) {
a.setElement(i, j, 0);
cout << " Elemento " << 1 << " " << 1 << " = " << a.getElement(l, c) << "\n";
}
}
a.setElement(0, 0, 1); // <- this is just for testing
system("pause");
}
iostream and the class header are both included at stdafx.h
Compiling it at MSVS 2013 breaks at
void Matriz::setElement(int pL, int pC, float value){
matriz[pL][pC] = value;
}
And we're not really sure why, the debugger is giving me
"Unhandled exception at 0x01092E27 in ConsoleApplication15.exe: 0xC0000005: Access violation writing location 0xCDCDCDD1."
We suspect however that something with the array is wrong, and when the program tries to write something into an element of it, it simply doesn't exist/can't be reached, making it impossible to change the value of that specific element.
We're thankful for any help or advice, fell free to suggest improvements or coding advices, learning new things is always good =).
I think your error is actually here: a.getElement(l, c). l and c are the bounds for the array, e.g. 2, when your largest index should only ever be 1.
The other serious flaw (pointed out by twsaef) is your constructor:
for (int i = 0; i<l; i++) {
matriz[l] = new float[c];
}
Should be
for (int i = 0; i<l; i++) {
matriz[i] = new float[c];
}
While I'm at it, this is redundant:
Matriz a(2, 2);
a.setC(2);
a.setL(2);
Because the constructor for Matriz will set l and c for you.
Also, what are you planning on doing with this:
float **m;
m = new float*[l];
for (int i=0; i<2; i++) {
m[i] = new float[c];
}
Currently it's not used for anything.
Then, as PaulMcKenzie pointed out, what will happen to your dynamically allocated memory when a Matriz instance goes out of scope?
As Matt McNabb pointed out, what if you need to resize a Matriz instance when setC() or setL() are called? At the moment, they only set the member variable and do nothing with the memory.

how to delete two-dimentional double array

I wrote two functions - one to create two-dimentional double array, and another one to delete it.
double** createMatrix(int n)
{
double **a = new double *[n];
for (int i=0; i < n; i++)
a[i] = new double[n];
return a;
}
void deleteMatrix(double** a, int n)
{
for (int i=0; i < n; i++)
delete [] a[i]; // ERROR HERE
delete []a;
}
Allocated array is working fine. But when I try to free it, I get an error (on a marked line): "project2.exe has triggered a breakpoint.".
I'm using Visual Studio 2012.
edit:
I created a full program:
int main()
{
const int n = 10;
double **m = createMatrix(n);
deleteMatrix(m, n);
return 0;
}
And it's working fine. Also, I found my problem. It was a typo in copyMatrix function.
for (int j=0; j <= n; j++) // should be < instead of <=
a[i][j] = originalMatrix[i][j];
Thanks a lot for your help!
The obvious solution is not to use an array in the first place.
How to create an n x n matrix ?
#include <iostream>
#include <vector>
using Row = std::vector<int>;
using Matrix = std::vector<Row>;
int main() {
size_t const n = 5;
Matrix matrix(Row(n), n);
}
Simple right ? And as a bonus, copy, move and destruction are provided free of charge.

dynamic allocation of int array in c++ and assigning value

I am new to c++ and i was trying to do folloing two things without help of std::vector( This was done earlier)
Define an array of integer and the size of array is not known to me.
Pass this array into another function and output all the values stored in array.
int _tmain()
{
int* a = NULL;
int n;
std::cin >> n;
a = new int[n];
for (int i=0; i<n; i++) {
a[i] = 0;
}
testFunction(a,n);
delete [] a;
a = NULL;
}
void testFunction( int x[], int n)
{
for(int i =0;i<n;++n)
{
std::cout<<x[i];
}
}
But i can see that its not allocating memory of 10 bytes and all the time a single memory is filled up with 0.
Can anyone please help me if i am lacking something ? Or is there any alternative way for this apart from vector.
Thanks in Advance
I modified with one thing as i realized that i put ++n instead of i
int _tmain()
{
int* a = NULL;
int n;
std::cin >> n;
a = new int[n];
for (int i=0; i<n; i++) {
a[i] = i;
}
testFunction(a,n);
delete [] a;
a = NULL;
}
void testFunction( int x[], int n)
{
for(int i =0;i<n;++i)
{
std::cout<<x[i];
}
}
I’m not sure I understand all yours problems but the typo
for(int i =0;i<n;++n) in testFunction led to a very long loop.
Write:
for(int i =0;i<n;++i)
this print yours n "0"

c++ using "indexing" over a 2D matrix, under this structure

don't know why but i get an error: after this structure i can't index the matrix, so i cant use the "indexing method" over the defined matrix.Can anyone tell me why? or how to fix it?
Header:
const int days=31;
const int exp=6;
struct Array{
int days;
int exp;
int **M;
};
Constuctor:
void constr(Array loc){
//Construct of 31*6 Matrix, were 31 nr. of days and 6 specific types:
//0-HouseKeeping, 1-Food, 2-Transport, 3-Clothing, 4-TelNet, 5-others
loc.days = days;
loc.exp = exp;
loc.M = new int*[loc.days];
for(int i=0; i<loc.days;i++ ){
loc.M[i] = new int[loc.exp];
for (int j = 0; j< loc.exp; j++){
loc.M[i][j] = 0;
}
}
}
Controller.cpp
void add(int cant,int tip, Array M){
//Adds to current day the amount to a specific type
currDay();
M[currentDay][tip] += cant; ////////////error
}
void insert(int zi,int tip,int cant, Array M){
//Adds to current day the amount to a specific type
M[zi][tip] = cant; ///////////error
}
void removeDay(int day, Array M){
for(int i = 0; i<6; i++)
M[day][i] = 0; ///////////error
//zi and tip ~ day type... for easier read.
//i need to manage the expenses of a family in a month doesn't matter which
ERROR: error: no match for 'operator[]'
UI(where constructor is used):
int main(){
Array M;
constr(M);
printMenu();
return 0;
}
You're not accessing the member:
M.M[currentDay][tip]
instead of
M[currentDay][tip]
Or you could define operator [] for your struct:
struct Array{
int days;
int exp;
int **M;
int*& operator[] (int idx) { return M[idx]; }
};
You are trying to call operator[] on the type array. You need to get the pointer member first.
M.M[day][i];
That said: You are not writing C++ but some obscure form of bad C. You might want to have a look at the book list and read one of them before pursuing coding any further.
You have at least two problems:
The first is that you are using the actual structure as the array, which wont work. Use e.g. M.M[day][i].
The second is that when you create the array, you pass the structure by value, this means it will be copied to a local variable in the constr function and the data will not be available in the function calling constr. Pass it as a reference instead, i.e. void constr(Array &loc).
The second problem can also be solved by using a constructor in the structure, instead of a separate function:
const int DAYS=31;
const int EXP=6;
struct Array{
int days;
int exp;
int **M;
// Constructor, called when an instance of structure/class is created
Array(){
days = DAYS;
exp = EXP;
M = new int*[days];
for(int i=0; i<days;i++ ){
M[i] = new int[exp];
for (int j = 0; j< exp; j++){
M[i][j] = 0;
}
}
}
// Destructor, called when structure/class is destroyed
~Array(){
if(M){
for(int i=0;i<days;i++){
if(M[i])
delete [] M[i];
}
delete [] M
}
}
// Copy constructor, called when instance of structure/class is copied
Array(const Array &array){
days = array.days;
exp = array.exp;
M = new int*[days];
for(int i=0; i<days;i++ ){
M[i] = new int[exp];
for (int j = 0; j< exp; j++){
M[i][j] = array.M[i][j];
}
}
}
};