Heap corruption on delete[] - c++

I've been getting heap corruption error on delete[] instruction. Project is worked on in VC++ 2008, its requirement (so please don't focus on that). Whole building process is working OK, but in run-time I get error: (prs_2013 is name of my project)
Windows has triggered a breakpoint in prs_2013.exe.
This may be due to a corruption of the heap, which indicates a bug in prs_2013.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while prs_2013.exe has focus.
The output window may have more diagnostic information.
This is code where error occurs, its just a fraction of whole project, but error is confined in this area:
// Function used for swapping row of matrix with new values
void Main::swap(double* matrix, double* row, unsigned index, unsigned size){
double temp = 0;
for(unsigned i = 0; i < size; i++){
temp = matrix[i*size + index];
matrix[i*size + index] = row[i];
row[i] = temp;
}
}
// Function that do some calculations, not really relevant for this problem
// but still used in code
double Main::determinat(double* matrix, unsigned size){
double ud = 0, du = 0;
for(unsigned j = 0; j < size; j++){
double ude = 1, due = 1;
for(unsigned i = 0; i < size; i++){
ude *= matrix[i*size + (i+j)%size];
due *= matrix[(size-i)*size + (i + j)%size];
}
ud += ude;
du += due;
}
return ud - du;
}
// Function in which error occurs
double* Main::get_x(double* matrix, unsigned size){
// error checking
if(size == 1){return NULL;}
double *x = new double[size];
x[0] = 1;
unsigned const temp_size = size-1;
double *temp = new double[temp_size * temp_size]; // temporary matrica
double *x0_coef = new double[temp_size]; // variable on which error occures
for(unsigned i = 0; i < temp_size; i++)
x0_coef[i] = matrix[i*size + 0] / s[0]; // s is class member, init in constructor s[0] != 0
for(unsigned i = 1; i < size; i++)
for(unsigned j = 1; j < size; j++)
if(i == j)
temp[(i-1)*size + j-1] = (matrix[i*size + j] - 1) / s[i];
else
temp[(i-1)*size + j-1] = matrix[i*size + j] / s[i];
double deltaS = determinat(temp, temp_size); // delta of system
for(unsigned i = 0; i < temp_size; i++){ // delta of vars
swap(temp, x0_coef, i, temp_size);
x[i+1] = determinat(temp, temp_size) / deltaS;
swap(temp, x0_coef, i, temp_size);
}
delete[] x0_coef; // place where error occures
delete[] temp;
return x;
}
But same thing happens if I switch delete[] x0_coef; with delete[] temp;, error occurs on temp;
As you can see in code I'm not using char, ie. making String so adding '\0' is useless because 0 is still valid value.
But now interesting part, I've tested swap function with this code:
#include <iostream>
using namespace std;
void swap(double* a, double* b, unsigned size){
double temp = 0;
for(unsigned i=0; i < size; i++){
temp = a[i];
a[i] = b[i];
b[i] = temp;
}
}
void main(){
double *a = new double[5],
*b = new double[5];
for(unsigned i=0; i < 5; i++){
a[i] = i;
b[i] = i*i;
}
swap(a, b, 5);
for(unsigned i=0; i < 5; i++)
std::cout << "a: " << a[i] << " b: " << b[i] << endl;
delete[] a;
delete[] b;
system("PAUSE");
}
And everything worked.
To be honest I'm at end of my wits, just spent 2-3 days trying to find out what is that I'm missing. But most of other topics are related on making char array, String, and general miss calculation of arrays length. And as is it shown in code I always carry arrays length to other functions.
I'm sure that there are better codes to do what I have to do, but this is solo-required project so I'm not looking in better functionality just to help me see what I'm doing wrong with arrays.

Your code corrupts memory when it writes into an out-of-bounds index of array temp. And when the heap is corrupted, anything can happen (like a crash on delete[] call).
Your temp array contains (size-1)*(size-1) items, while it is treated it as a size*(size-1) array inside the double loop: temp[(i-1)*size + j-1] = ... (because you multiply "the first index" by size).
I guess replacing it with temp[(i-1)*temp_size + j-1] will solve the problem.

Related

C++ Memory leak error when resizing C++ dynamic array

The code below converts lets say array 3,9,3 to sorted array of integers 3,3,3,3,3 by converting 9 into sum of maximum possible parts.
The link to code/algorithm used in this code is answered at
https://stackoverflow.com/a/75331557/21145472
I am struck in this C++ code. When I ran it yesterday it was fine but today it gives memory leak error when function resizeArray() is run third time.
Please help fix this memory leak
#include<cmath>
#include <algorithm>
#include <iterator>
using namespace std;
void resizeArray(int *orig, int size, int newSize) {
int *resized = new int[newSize];
for (int i = 0; i < size; i ++)
resized[i] = orig[i];
delete [] orig;
orig = resized;
}
int main(){
int n = 3;
int *arr = new int[n];
int arrLength = n;
arr[0] = 3;
arr[1] = 9;
arr[2] = 3;
int *arrSorted = new int[0];
int sortedArrayLength = 0;
int temp;
unsigned long long int limit = 10e4;
long long parts = 0;
int extra = 0;
int mainArrayIndex = 0;
for(int i = 0; i<n/2; i++){
temp = arr[i];
arr[i] = arr[n-i-1];
arr[n-i-1] = temp;
}
for(int i = 0; i < n; i++){
parts = floor((arr[i] - 1) / (limit)) + 1;
limit = arr[i] / parts;
extra = arr[i] % parts;
for(int index = 0; index < extra; index++){
resizeArray(arrSorted, sortedArrayLength, sortedArrayLength + 1);
arrSorted[mainArrayIndex] = limit+1;
mainArrayIndex+=1;
sortedArrayLength+=1;
}
for(int index = 0; index < parts - extra; index++){
resizeArray(arrSorted, sortedArrayLength, sortedArrayLength + 1);
arrSorted[mainArrayIndex] = limit;
mainArrayIndex+=1;
sortedArrayLength+=1;
}
}
cout << "Array sorted steps taken" << " " << sortedArrayLength - arrLength;
cout << endl;
for(int i = 0; i < sortedArrayLength; i++){
if(i == 0)
cout << "[";
cout << arrSorted[i];
if(i < sortedArrayLength - 1)
cout << ", ";
if(i == sortedArrayLength - 1)
cout << "]";
}
delete []arr;
delete []arrSorted;
}
Your helper function's orig = resized; doesn't reassign your main function's arrSorted as you intend. Use a reference:
void resizeArray(int *&orig, ...) {
(That and the lack of including iostream are the only correctness issues I see, and this fix got rid of the error.)

Code Exiting on above 500,000 number of input

I was performing sorting algorithm to calculate their runtime to execute, in which I was giving millions of number of input to sort, but my code is exiting on above 500,000 input and not showing any output. Is there anyway I can solve it.
int size;
cout<<"Enter size of the array: "<<endl;
cin>>size;
int a[size];
for(int i=0;i<size;i++)
{
a[i]=rand()%size;
}
int temp = 0;
double cl=clock();
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (a[j] < a[i])
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
double final=clock()-cl;
cout<<final/(double)CLOCKS_PER_SEC;
}
You code crashes on 500'000 input because of stack overflow, you're allocating array on stack of too big size:
int a[size];
Stack size is usually few megabytes at most.
Also it is probably an extensions not of all compilers to have dynamically allocated array on stack, usually size should be a compile time constant.
To overcome stack crash either you have to use std::vector which can provide any size as big as there is free memory, for that do:
std::vector<int> a(size);
(also #include <vector>). Or you may use dynamically allocated array through new operator:
int * a = new int[size];
For this case don't forget to do delete[] a; at the end of program (see docs here).
Don't forget that input 500'000 takes very much of time using your bubble sort. For example 10 times less, 50'000, takes around 10 seconds on my machine.
Full working code using std::vector plus code formatting:
Try it online!
#include <iostream>
#include <vector>
using namespace std;
int main() {
int size;
cout << "Enter size of the array: " << endl;
cin >> size;
std::vector<int> a(size);
for (int i = 0; i < size; i++) {
a[i] = rand() % size;
}
int temp = 0;
double cl = clock();
for (int i = 0; i < size; i++) {
for (int j = i + 1; j < size; j++) {
if (a[j] < a[i]) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
double final = clock() - cl;
cout << final / (double)CLOCKS_PER_SEC;
}

Segmentation fault when remove duplicate value in pointer array

When debugging, I found that segmentation fault caused after copy from temp array (b) to original array (a), I don't know how to solve this, can you guys help me on that?
#include <iostream>
using namespace std;
int main() {
int n;
cout << "n = ";
cin >> n;
int *a = new int[n];
for (int i = 0; i < n; i++)
cin >> a[i];
cout << "\nNumber to remove: ";
int k;
cin >> k;
for (int i = 0; i < n; i++)
{
while (a[i] == k && i < n - 1)
{
int *b = new int[n]{0};
for (int j = 0; j < i; j++)
b[j] = a[j];
for (int j = i + 1; j < n; j++)
b[j - 1] = a[j];
a = NULL;
delete a;
n--;
int *a = new int[n];
for (int j = 0; j < n; j++)
a[j] = b[j];
}
}
cout << "Result: ";
for (int i = 0; i < n; i++)
cout << a[i] << " ";
}
The problem with this implementation lies here:
a = NULL;
delete a;
When you use the delete keyword you are telling the compiler to free the memory allocated by a new keyword, in this case you have a which is a pointer to the memory allocated by int *a = new int[n];. a at this point would probably be a 32bit address for example 0xbfebd5c0, i said probably because it depends on the architecture of the machine, however... after that you are setting a to NULL resulting in a being 0x0, at the next while condition check a is NULL and accessing 0x0 + i is not possible due to safety reasons imposed by the OS (no one gave you access to this location). The solution to your specific problem would be removing a = NULL; and delete a; as both these operations interfere with the while condition check.
I would suggest to take another approach at solving this problem since you really don't need to do this many dynamic allocations.

Linear Recursion reverse the array

Can not figure out why my recursion function does not work?
#include <iostream>
using namespace std;
int ReverseArray(int* A, int i, int j);
int main()
{
int j = 10;
int i = 0;
int *b = new int[j];
for (int i = 0; i <= 10; i++)
b[i] = i;
for (int i = 0; i <= 10; i++) //just to compare the old and new array
cout << b[i] << endl; //just to compare the
for(int i = 0; i <= j; i++)
cout << ReverseArray(b,i,j) << endl;
system("pause");
return 0;
}
int ReverseArray(int* A, int i, int j)
{
if (i <= j)
{
swap(A[i], A[j]);
ReverseArray(A, i + 1, j - 1);
}
return A[i];
This should return
10,9,8....
but it returns
10,0,9,1...
I don't get why its happening
You have a double loop, once here:
for(int i = 0; i <= j; i++)
cout << ReverseArray(b,i,j) << endl;
and once here:
ReverseArray(A, i + 1, j - 1);
Calling a function recursively is equivalent to looping over it. To reverse a list, you only need to loop over it once, and what you've done is the equivalent of a doubly-nested loop. So let's get rid of
for(int i = 0; i <= j; i++)
and change
cout << ReverseArray(b,i,j) << endl;
to just
ReverseArray(b,i,j);
Then you are only reversing b, nothing else. To print, just loop from 0 to 10 and print each element.
Also, unrelated, but keep in mind that the code as you have it right now touches memory that has not been allocated to the heap.
int *b = new int[j];
creates j (here, 10) ints, at the physical memory locations b, b + 1, b + 2, ..., b + 9. b[i] then gets the memory held at b + i, that is, it gets *(b + i). Several of your loops try to do things with b[10], and there has not been enough memory allocated for it. This will result in undefined behaviour (i.e. many different things can happen depending on your compiler and the state of your computer). With 'system("pause");' removed (which shouldn't affect code execution) on my machine, this gave me a memory allocation for that reason.
Solution here is to either have
int *b = new int[j+1];
or replace all your <= signs with <.

Run-Time Check Failure #2

I have problem with such error: Run-Time Check Failure #2 - Stack around the variable 'numb' was corrupted.
It appears at the last bracket of such function:
int problem20()
{
int res = 0, i;
int numb[160];
for(i = 0; i < 160; i++)
numb[i] = 0;
numb[0] = 1;
for(i = 1; i < 100; i++)
{
multiply(numb, i, numb, 160);
}
for(i = 0; i < 160; i++)
res += numb[i];
return res;
}
EDIT:
void multiply(int* a1, int a2, int* res, int l)
{
int temp, i, m = a2, k;
for(k = 0; m > 0; k++)
m /= 10;
int *result = new int[l + k];
for(i = 0, temp = 0; i < l; i++)
{
result[i] = a1[i] * a2 + temp;
temp = result[i] / 10;
result[i] %= 10;
}
for(i = l; i < l + k; i++)
{
result[i] = temp % 10;
temp /= 10;
}
memcpy(res, result, sizeof(int) * (l + k));
delete[] result;
}
function miltiply just multiply numb by i and give result to the third argument. This function is ok, it was tested earlier.
Your problem is that you pass numb as the res argument for the multiply function. The multiply function creates an array that has size l + k and then tries to copy it to the numb array with size l, this means that you are going out of the bounds of the numb array which in turn triggers this problem.
I would suggest turning the int* arguments to references to std::vector in order to avoid the need to manually allocate a temporary array.