Повреждение кучи во время free()

Вот отладочная информация,

HEAP[opencv_CoTraining2.exe]: Heap block at 0AD15168 modified at 0AD15594 past requested  size of 424
Windows has triggered a breakpoint in opencv_CoTraining2.exe.

This may be due to a corruption of the heap, which indicates a bug in opencv_CoTraining2.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while opencv_CoTraining2.exe has focus.

The output window may have more diagnostic information.

и вот мой код:

void GetKCent(Mat& mat)
{
    double** tmp=(double**)calloc(mat.rows,sizeof(double*));
    double f[128];
    memset(f,0,sizeof(f));
    double max=0;
    for (int i=0;i<mat.rows;i++) 
    {
        tmp[i]=(double*)calloc(mat.cols,sizeof(double));
        for (int j=0;j<mat.cols;j++)
        {
                tmp[i][j]=mat.at<float>(i,j);
                if (tmp[i][j]>max) max=tmp[i][j];
        }
    }
    for (int i=0;i<mat.cols;i++) for (int j=0;j<mat.rows;j++) tmp[j][i]/=max;
    k_means(tmp,mat.rows,128,K_CLUSTER,KMEANSDIS,kcent);
    for (int i=0;i<K_CLUSTER;i++) for (int j=0;j<128;j++) kcent[i][j]*=max;
    for (int i=0;i<mat.rows;i++)free(tmp[i]);
    free(tmp);
}

Ошибка произошла в этой строке,

for (int i=0;i<mat.rows;i++)free(tmp[i]);

а функция k_means() не изменяет первый параметр. Кто может мне помочь?

P.S. Вот определение k_means()

int k_means(double **data, int n, int m, int k, double t, double **centroids)

а вот и _двойной** кцент_

kcent=(double**)calloc(K_CLUSTER,sizeof(double*));
for (int i=0;i<K_CLUSTER;i++) kcent[i]=(double*)calloc(128,sizeof(double));

Я думаю, что эта часть правильная.


person wcwswswws    schedule 21.06.2013    source источник
comment
Вы правильно вызываете функцию? все остальное выглядит нормально   -  person tay10r    schedule 21.06.2013
comment
k_means вообще меняет mat.rows? Я скомпилировал это без функций k_, и он отлично работал с valgrind.   -  person tay10r    schedule 21.06.2013
comment
Вы пропустили определение kcent, возможно, вы выходите за его рамки? Проблема, вероятно, заключается в повреждении памяти указателей до того, как вы доберетесь до файла free.   -  person Mark Ransom    schedule 21.06.2013
comment
Вы пропустили какой-то код или f[] действительно не используется?   -  person Michael Burr    schedule 21.06.2013
comment
Настройте окно памяти отладчика так, чтобы отображалась память после конца поврежденной строки. Шаг через код — вы сможете легко увидеть, когда память будет изменена, и сможете определить виновника.   -  person Michael Burr    schedule 21.06.2013


Ответы (2)


Сообщение об ошибке кажется очень ясным, что это повреждение кучи.

Попробуйте переместить цикл free() for над вызовом функции k_means() и закомментировать остальную часть вашей программы.

Я подозреваю, что это то, что портит кучу!

Если этот эксперимент правильно освобождает память, вы знаете, что ошибка в функции k_means()...

person sukumarst    schedule 22.06.2013
comment
Да... наконец-то я нашел ошибку в k_means() и знаю, что исправил ее... спасибо... - person wcwswswws; 23.06.2013

вы не используете адрес указателя, полученный от calloc, в free, поэтому начальный адрес памяти, указанный аргументом free(), отличается. Если я не ошибаюсь, вы не можете получить целую кучу памяти, а затем освободить их по частям, если это то, чего вы пытаетесь достичь. По крайней мере, с malloc.

В free() используйте то же значение, что и в calloc().

person Asaf Sh.    schedule 21.06.2013