Why do i get a memory heap error?

Hello,

So from coding this n x n linear equation solver, I have been able to get it working just fine. But I receive a memory error in the DeleteVector(c) in my int main function?

Could anyone suggest why this might be causing this error? - Line 314

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
#include <iostream>
#include <math.h>
#include<iomanip>

using namespace std;

//Functions for making  and deleting vectors and matrices
double* MakeVector(int i)
{
    //Dynamically allocate memory for vector array
    double* vector = new double[i];
    return vector;
}
double** MakeMatrix(int rows, int cols)
{
    double** matrix;
    matrix = new double* [rows];

    for (int x = 0; x < rows; x++)
    {
        matrix[x] = new double[cols];
    }
    return matrix;
}
double** MakeAugmentedMatrix(double** A, double* b, int i, int j)
{
    double** AugmentedMatrix;
    AugmentedMatrix = MakeMatrix(i, j + 1);

    //Assign elements of matrix A to augmented matrix
    for (int x = 0; x < i; x++)
    {
        for (int y = 0; y < j; y++)
        {
            AugmentedMatrix[x][y] = A[x][y];
        }
    }

    //Assign elements of column vector b to augmented matrix
    for (int x = 0; x < i; x++)
    {
        AugmentedMatrix[x][j] = b[x];
    }

    cout << "The augmented matrix is " << endl;

    DisplayMatrix(AugmentedMatrix, i, j + 1);

    return AugmentedMatrix;
}
void InitialiseMatrix(double** A, int rows, int cols)
{
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            A[i][j] = 0.0;
        }
    }

    cout << "The matrix has been initialised with the following values" << endl;
    DisplayMatrix(A, rows, cols);
}
void InitialiseVector(double* b, int i)
{
    for (int x = 0; x < i; x++)
    {
        b[x] = 0.0;
    }
    cout << "The vector has beein initialised with the values " << endl;
    DisplayVector(b, i);
}

void DeleteMatrix(double** A, int rows, int cols)
{
    for (int i = 0; i < rows; i++)
    {
        delete[]A[i];
    }
    delete[] A;
}
void DeleteVector(double* b)
{
    delete[] b;
}
void EnterMatrixElements(double** A, int rows, int cols)
{
    cout << "What data would you like to enter for the matrix?" << endl;
    cout << "The matrix has a size of " << rows * cols << " elements" << endl;
    double temp;
    for (int x = 0; x < rows; x++)
    {
        for (int y = 0; y < cols; y++)
        {
            cout << "What is number you would like to enter?" << endl;
            cin >> A[x][y];
        }
    }
}
void EnterVectorElements(double* b, int size)
{
    cout << "Enter the values for each element in your column vector" << endl;
    //Enter values for vector array elements
    for (int i = 0; i < size; i++)
    {
        cin >> b[i];
    }
}
void DisplayMatrix(double** matrix, int rows, int columns)
{
    cout << "{";
    for (int i = 0; i < rows; i++)
    {
        cout << "{";
        for (int j = 0; j < columns; j++)
        {
            cout << setprecision(3) << setw(6) << matrix[i][j] << ", ";
        }
        cout << "}" << endl;
    }
    cout << "}";
}
void DisplayVector(double* b, int size)
{
    cout << "The elements of the vector are {";
    for (int i = 0; i < size; i++)
    {
        cout << b[i] << endl;
    }
    cout << "}";
}

//Functions for algorithm steps
double** Forward_Elimination(double** A, int rows, int cols)
{
    //Set up a for loop to go through each row for each column
    for (int k = 0; k < rows; k++)
    {
        //Declare a variable for the index for the highest no in the column and the max value itself
        int row_index_max = k;
        double max = A[row_index_max][k];

        //Use a for loop to cycle through the rest of the column to find if there is a higher value than the one above
        for (int i = k + 1; i < rows; i++)
        {
            if (abs(A[i][k]) > max)
            {
                max = A[i][k];
                row_index_max = i;
            }

            //Check if the row with the highest number is greater than the current one, if so, swap the rows around
            if (max != k)
            {
                SwapRows(A, k, row_index_max, rows, cols);
            }
            cout << "Performing an elimination pass on augmented matrix" << endl;
            Elimination_Pass(A, rows, cols, k);
            DisplayMatrix(A, rows, cols + 1);
        }
    }
    return A;
}
double** Elimination_Pass(double** A, int rows, int cols, int k)
{
    //For loop to make an elimination pass of rows below kth diagonal sequentially
    for (int i = k + 1; i < rows; i++)
    {
        //Declare and assign factor f to divide each row by
        double f = A[i][k] / A[k][k];

        // Construct a for loop to subtract a factor of f from the kth row
        for (int j = k + 1; j <= cols; j++)
        {
            cout << "Making an  elimination pass by subtracting f x row from each element in the row" << endl;
            A[i][j] = A[i][j] - (A[k][j] * f);
            cout << A[i][j] << " = " << A[i][j] << " - " << A[k][j] << " x " << f << endl;

            //Filling lower triangular matrix with zeros
            cout << "Completing the lower triangular matrix" << endl;
            A[i][k] = 0;
            DisplayMatrix(A, rows, cols + 1);
        }
    }
    return A;
}
void SwapRows(double** A, int destination_row, int moving_row, int i, int j)
{
    for (int x = 0; x < i + 1; x++)
    {
        double temp = A[destination_row][x];
        A[destination_row][x] = A[moving_row][x];
        A[moving_row][x] = temp;
        DisplayMatrix(A, i, j + 1);
    }
}
double** FormUMatrix(double** A, int i, int j)
{
    double** U = MakeMatrix(i, j - 1);
    //Assign values to U matrix
    for (int x = 0; x < i; x++)
    {
        for (int y = 0; y < j - 1; y++)
        {
            U[x][y] = A[x][y];
        }
    }

    cout << "The U vector is " << endl;
    DisplayMatrix(U, i, j - 1);

    return U;
}
double* FormCVector(double** A, int i)
{
    double* c = MakeVector(i);
    InitialiseVector(c, i);

    for (int x = 0; x < i; x++)
    {
        c[i] = A[x][i];
    }
    cout << "The c vector is" << endl;
    DisplayVector(c, i);
    return c;
}

double* BackwardSub(double** U, double* c, int rows, int cols)
{
    /*Use a for loop to start from last solution, which would be the augmented matrix passed to this after
    forward elimination, AugMat[i][j]*/
    for (int i = rows - 1; i >= 0; i--)
    {
        //Assign first solution, from the bottom row to the c matrix
        c[i] = U[i][cols];

        /*Having passed an upper triangle matrix, begin to subsitute 1st solution to solve others back up the
        rows*/
        for (int j = i + 1; j < cols; j++)
        {
            /*Complete the summation as per given formula*/
            c[i] = c[i] - U[i][j] * c[j];
        }
        /*To obtain unknowns, use formula x[i] = x[i] / U[i][i]*/
        c[i] = c[i] / U[i][i];
        DisplayVector(c, cols);
    }
    return c;
}

int main()
{
    cout << "This program will compute unknown values to a system of linear equtions in matrix form" << endl;

    int i = 0;
    int j = 0;

    /*do while loop to get used input, and to check if it is a square matrix*/
    do
    {
        cout << "What are the dimensions of your square matrix ?" << endl;

        cin >> i;
        cout << "The matrix has " << i << " rows " << endl;
        cin >> j;
        cout << "The matrix will have " << j << " columns " << endl;

        if (i == j)
        {
            cout << "You've correctly entered the elements for the square matrix" << endl;
            break;
        }
        else
        {
            cout << "It isn't a square matrix, re enter the details" << endl;

            cin >> i;
            cout << "The matrix has " << i << " rows " << endl;
            cin >> j;
            cout << "The matrix will have " << j << " columns " << endl;
        }
    } while (i != j);

    /*Call functions to allocate memory and initialise each matrix and vector*/
    double** matrix = MakeMatrix(i, j);
    double* x = MakeVector(i);

    InitialiseMatrix(matrix, i, j);
    InitialiseVector(x, i);

    EnterMatrixElements(matrix, i, j);
    EnterVectorElements(x, i);

    double** AugMat = MakeAugmentedMatrix(matrix, x, i, j);

    DeleteMatrix(matrix, i, j);
    DeleteVector(x);

    /*Comlpete forward elimination */
    Forward_Elimination(AugMat, i, j);


    double* c = FormCVector(AugMat, i);
    InitialiseVector(c, j);

 
    double* y = BackwardSub(AugMat, c, i, j);

    //Delete memory for vectors and matrices
    DisplayVector(y, j);

    DeleteMatrix(AugMat, i, j);

    DeleteVector(c);
    DeleteVector(y);

    return 0;
}
Last edited on
it gives a bunch of nan and inf in the results as well. I had to rearrange functions as you call things before they exist. Its <cmath> for c++.


still looking...

I believe your backsub is going out of bounds and damaging c, making it crash when it deletes it. Check all the bounds on C in backsub carefully.
Last edited on
> Could anyone suggest why this might be causing this error?
Can you provide us with a meaningful data sample to feed into the program?
Your variable names are terrible!
Anyway, in FormCVector, look at line 221 above.
You're assigning to c[i], where i is (inexplicably) the size, so it's out-of-bounds.
You mean it to be c[x].
Hello dutch and jonnin

Anyway, in FormCVector, look at line 221 above.
You're assigning to c[i], where i is (inexplicably) the size, so it's out-of-bounds.
You mean it to be c[x].


I believe your backsub is going out of bounds and damaging c, making it crash when it deletes it. Check all the bounds on C in backsub carefully.


Thanks! I will look into this and see how it goes. Hopefully by tweaking these things I won't get a memory error

Your variable names are terrible!

Could you suggest the common standard/methodology I should adopt? I was trying my best to use linear algebra terms as I done it first on paper.
I tested it with the following values

(1,1,3
3,-2,4)

And i get 1 and 2 correctly

{{3.0, 2.0,-4.0, 3.0},
{2.0, 3.0, 3.0, 15.0},
{5.0, -3, 1.0, 14.0} };

And I get 3,1 and 2 which match with my own solutions from my textbook examples.
Could you suggest the common standard/methodology I should adopt? I was trying my best to use linear algebra terms as I done it first on paper.


math code vs names is one of those things that is hard to get agreement upon. If you go with the math approach, you have crap names like x and y or a and b, and that is fine as long as the coder reading it knows the common math useage. One of the biggest messes we had at my first job was some smart programmer renamed all the variables for all the derivatives in a flight sim to verylongvariablenameswithlotsawords which made the math unreadable. No one wants to see a 5 or 6 symbol simple equation turned int to 3 lines of code due to giant variable names but on the flipside someone who has no clue what you are doing (its clear here, at least) does not really want to see line after line of x = a*b/c either, with nary a comment anywhere to explain what any of it is doing.

I think your issue here is a mix of having a simple problem/small program combined with math issues /jargon combined with the occasional one letter variable name at random.

split the difference. If the names affect the way the math looks in code so that its unclear what the math is, keep it math like.
if it does not matter, use code names and make it easier to read.

double* MakeVector(int i) //i?? what is i? how about size, length, something like that? A function's variable parameters should clue the user into what value goes there; some codeing tools show the prototype when you start typing it and the hints in the names help remember what order which values go into it, etc.

Fix the [x] error first. I am not 100% sure about backsub; I said that because commenting out calls in main until the delete command worked indicated that it was damaged in backsub on my machine. That isnt the most reliable method.
Topic archived. No new replies allowed.