Поврежденная куча - C - PullRequest
       23

Поврежденная куча - C

0 голосов
/ 27 июля 2011

Я получаю следующее сообщение об ошибке, когда запускаю код в режиме отладки.

Windows сработала точку останова в Linear Equations 331.exe.

Это может быть связано с повреждением кучи, что указывает на ошибку в Linear Equations 331.exe или любой другойиз загруженных им библиотек.

Затем идет перерыв / продолжение.

Код использует итерационный метод Гаусса-Зиделя для решения системы линейных уравнений.В этом случае мне нужно найти общее количество растяжек (X) для 3 последовательных банджи-шнуров, к которым прикреплены 3 человека (A, B, C).Каждое решение имеет различную перестановку подключенных людей (т. Е. A, B, C; A, C, B; B, A, C и т. Д.)

Нам был предоставлен файл заголовка выделения памяти, называемый alloc.ч, хотя я не до конца понимаю, как это работает, что может быть причиной моей проблемы.Он работал нормально, прежде чем я начал использовать ALLOCATE () для большего количества переменных.Любая помощь в объяснении, почему это происходит, была бы очень полезна.

Основной код - первый.Заголовочные файлы находятся внизу.Извините, если код немного грязный.Я старался комментировать как можно лучше:

#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_WARNINGS


#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "allocate.h"
#include "iter.h"

void position_solve(int n,int k,double X[], double x[],double order[]);
void inverse(int n, double A[],double X[],double b[]);
void swap(double *,double*);
void permute(int n, double a[]);
int noofpermutations();
void next(int n,double a[]);
void permutation(int n, double a[]);
int count = 0;

int main(void) 
    {
int i,j,k,num=0, n=3, p=noofpermutations(n);
    double *A = NULL, *m = NULL, *X = NULL,* b= NULL,*K=NULL, *x=NULL, *order=NULL,   *length=NULL;

/* Allocate the required memory */
ALLOCATE(A, double, n * n);
ALLOCATE(m, double, n * p);
ALLOCATE(b, double, n);
ALLOCATE(x, double, n * p);
ALLOCATE(K, double, n * p);
ALLOCATE(X, double, n);
ALLOCATE(order,double, n);
ALLOCATE(length,double,1);


/*Defining the Order of A,B,C jumpers where 1 = A, 2 = B, 3 = C*/
printf("+-----------------------------------------------------------------------------+\n");
printf("The Order of Bungee Jumpers A,B and C is represented by \n1,2,and 3 respectively. \n");
printf("\n+-----------------------------------------------------------------------------+\n");

for(i=0;i<n;i++){
    order[i] = i+1;
    b[i] = 0;
}

length[0] = 0;
/*Hardcoding k(spring constant),x(initial length of each bungee cord) and m(mass in kg) for 3 bunjee jumpers*/
K[0] = 50;
K[1] = 100;
K[2] = 50;

m[0] = -60*9.81;
m[1] = -70*9.81;
m[2] = -80*9.81;

x[0] = 20;
x[1] = 20;
x[2] = 20;

for(i=3;i<n*p;i++){
K[i] = 0;
m[i] = 0;
x[i] = 0;
}

/*Generate Permutations of K,m for the given Order of Bungee Jumpers */
permutation(n,K);
permutation(n,m);
permutation(n,order);

/*Calculate A matrix*/
for(k=0;k<p;k++){
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            if(i==j){
                A[i*n + j] = -K[k*n + i] - K[k*n + j];
            }
            else if(j == (i+1)){
                A[i*n+j] = K[k*n + j];
                A[j*n+i] = K[k*n + j];
            }
            else if(j>(i+1)){
                A[i*n + j] = 0;
            }
        }
    }

    printf("\nFor a Bungee Jumper order %1.0lf %1.0lf %1.0lf :\n",order[k*n],order[k*n+1],order[k*n+2]);

    /*Determine multiple X (stretch of bungee in m) vecotrs*/
    /*Extract a single RHS vector (from B) into b*/
    for(i=0;i<n;i++){
        b[i]= m[k*n + i];
    }
    /*Perform Iterative Method*/
    iter_solve(n, A, b, X);

    /* Output X solutions*/
    printf("\nX = [\n");
    for (j = 0; j < n; j++) {
            printf("%f ", X[j]);
        printf("\n");
    }
    printf("]\n");
    /*Determine Order of Jumpers*/
    position_solve(n,k,X,x,order);

    printf("--------------------------------------------\n\n");

    /*If A,B,C Permutation find inverse*/
    if(((int)(order[k*n])==1) && ((int)(order[k*n+1])==2)){
        inverse(n,A,X,b);
    }
}
/* Free allocated memory */

FREE(A);
FREE(b);
FREE(x);
FREE(X);
FREE(order);
FREE(length);
FREE(m);

return 0;
}

void iter_solve(int n, double A[], double b[], double x[])
{
int i, j, k = 0;
double sum, delta = 0.2, x_store;

/*Check for division by zero and guess X=Zeros*/
for(i=0;i<n;i++){
    x[i] = 0;
    if(fabs(A[i*n + i]) < ZERO){
        //exit if division by zero occurs
        printf("Division by zero occurs. Preconditioning A matrix may be required.");
        exit(EXIT_FAILURE);
    }
}

/*Perform Gauss-Seidel Iteration*/
while( (delta>TOL) && (k<MAX_ITER) ){
    for(i = 0; i < n; i++){
        x_store = x[i];
        sum = 0;
        /*Sum for j<i*/
        for(j = 0;(j < i); j++){
            sum += A[i*n +j]*x[j];
        }
        /*Sum for i>j*/
        for((j=i+1);j<n;j++){
            sum += A[i*n +j]*x[j];
        }
        //Determine X value for current iteration
        x[i] =  (b[i]- sum)/A[i*n + i];

        /*Find the residual difference using L1-norm*/
        if((k>0) && (delta>((fabs(x[i] - x_store)/fabs(x[i]))))){
            delta = fabs(x[i] - x_store)/fabs(x[i]);
        }
    }
    k++;
}
/*Print Number of iterations*/
printf("\nNumber of iterations: %d using a tolerance of %f \n",k,TOL);
}

void position_solve(int n,int k,double X[], double x[],double order[])
{
int j, position;
double length = 0;
for (j = 0; j < n; j++) {
            //printf("%f ", X[j]);
            position = (int)(order[k*n +j]);
            length += X[j] + x[position]; 
            printf("Bungee Jumper %i: %lf meters\n",position,length);
            /*Reset X vector to zero*/
            X[j] = 0;
        printf("\n");
    }
} 

void inverse(int n, double A[],double X[],double b[])
{
int i,j;
double *Inv_A;
ALLOCATE(Inv_A, double, n * n);

for(i=0;i<n;i++){
    for(j=0;j<n;j++){
        if(i==j){
            b[i]=1;
        }
        else{
            b[i]=0;
        }
    }
    iter_solve(n,A,b,X);
    for(j=0;j<n;j++){
        Inv_A[i*n +j] = X[j];
    }
}
printf("\nInverse A = [\n");
for(i=0;i<n;i++){
    for(j=0;j<n;j++){
        printf(" %lf ",A[i*n +j]);
    }
    printf("\n");
}
printf(" ]\n");
FREE(Inv_A);
}
void swap(double *p1,double *p2)
{   double temp;
temp = *p1;
*p1 = *p2;
*p2 = temp;
}

int noofpermutations(int n)
{   int permutations=1,i;
for(i=1;i<=n;i++)
permutations=permutations*i;
return permutations;
}

void next(int n,double a[])
{   int i;
for(i=0;i<n;i++){
if(count < noofpermutations(n)){
    a[(count+1)*n + i] = a[count*n +i];
} 
}
count++;
}

void permute(int n, double a[])
{   int j;
while(count<noofpermutations(n)){
for(j=0;j<n-1;j++)
{  swap(&a[count*n + j],&a[(count*n) + (j+1)]);
next(n,a);
}
swap(&a[(count*n)],&a[(count*n) + 1]);
next(n,a);
for(j=n-1;j>0;j--)
{  swap(&a[(count*n)+ j],&a[(count*n) + (j-1)]);
next(n,a);
}
swap(&a[(count*n) + (n-1)],&a[(count*n) + (n-2)]);
next(n,a);
}
}

void permutation(int n,double a[])
{
permute(n,a);
count = 0;

allocate.h

/*
 * allocate.h
 *
 * Dynamic memory allocation macros
 */

 #ifndef _allocate_h_
 #define _allocate_h_

#include <stdio.h>
#include <stdlib.h>

#define ALLOCATE(VAR,TYPE,SIZE) \
  { \
 (VAR) = (TYPE *) calloc ((SIZE), sizeof(TYPE)); \
 if ((VAR) == NULL) { \
  fprintf (stderr, "ALLOCATE: Memory allocation failed (%s:%d) [%d]\n", __FILE__, __LINE__, (SIZE)); \
  exit (EXIT_FAILURE); \
} \
  }


 #define FREE(VAR) \
{ \
free ((VAR)); \
(VAR) = NULL; \
}

#endif

/*
 * iter.h
 *
 * Routine for solving square systems of linear equations with
 * multiple right-hand sides AX=B using Gauss-Seidel iterative methods
 */


/* Zero tolerance for double precision */
#define ZERO 1.0E-12

/* Tolerance for iteration relative change */
#define TOL  0.01

/* Maximum number of iterations */
#define MAX_ITER 500

void iter_solve(int n, double A[], double b[], double x[]);
/*
 * Iterative solver, x = (b - LU * xp) / D
 * Input:
 *   n   = size of matrix A
 *   A   = factorised A matrix, (nxn) stored by row
 *   b   = right-hand side vector, (nx1)
 * Output:
 *   x = solution vector, (nx1)
 * Failure scenarios:
 *   Division by "zero"
 */

Ответы [ 2 ]

0 голосов
/ 08 мая 2013

dll может привести к повреждению кучи, если библиотека времени выполнения для связывания вашего проекта отличается от библиотеки

0 голосов
/ 28 июля 2011

Когда его ошибка возникает в отладчике, он должен сообщить вам, где вы находитесь в программе, где он происходит - возможно, это позволит вам определить, какая ячейка памяти повреждена.

Обратите внимание, что адрес, перезапустите программу в отладчике, установите точку останова после распределения, затем установите точку останова для данных в этой ячейке памяти и запустите, чтобы увидеть, кто ее удаляет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...