Heap corruption on delete[]
Asked Answered
R

1

7

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.

Roden answered 8/6, 2013 at 11:58 Comment(3)
This is the kind of things that happen when you do manual memory management with raw pointers, new, and delete (or their array counterparts). I would suggest using RAII wrappers such as std::vector instead. Boost also has classes for multi-dimensional arraysPenetrate
This is the kind of things that happen when one does an INCORRECT memory management with raw pointers.Llamas
I know i could used already made libs, but that is out of requirement for this project. Except <iostream>, <fiosteam>, <cstring> and <cmath> I cant use any other lib. I really cant show you but i even implemented linked lists and round-buffer. And this kind of thing happen when I try to do whole project in 2 days without a sleep.Roden
L
10

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.

Llamas answered 8/6, 2013 at 12:4 Comment(2)
Thank you very much. I've gone blind staring to my monitor for 10 hours. Error made due copy/paste from test code.Roden
Wanted to chime in and to say that I was getting a runtime error upon delete but without any error message. It took me a while to find out that this was the cause. I allocated to little memory for some arrays and used out of bounds indices.Exhilarant

© 2022 - 2024 — McMap. All rights reserved.