腐败的堆 - C.

时间:2011-07-27 19:17:03

标签: c memory memory-management heap-corruption

在调试中运行代码时,我不断收到以下错误消息。

  

Windows已触发线性方程式331.exe中的断点。

     

这可能是由于堆的损坏,这表明存在错误   Linear Equations 331.exe或它加载的任何DLL。

然后它会出现休息/继续。

该代码使用Gauss-Siedel迭代方法求解n x n线性方程组。在这种情况下,我需要找到3个串联弹力绳的拉伸总量(X),其上有3个人(A,B,C)。每种解决方案都有不同的附加排列(即A,B,C; A,C,B; B,A,C等)

我们提供了一个名为alloc.h的内存分配头文件,虽然我不完全理解它是如何工作的,这可能导致我的问题。在我开始使用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 :(得分:0)

当他在调试器中发生错误时,它应该告诉你它在程序中的位置 - 希望这可以让你识别哪个内存位置被破坏了。

注意地址,在调试器中重新启动程序,在分配发生后设置断点,然后在该内存位置设置一个数据断点并运行以查看谁将其丢弃。

答案 1 :(得分:0)

如果用于链接项目的运行时库与库的

不同,则dll可能会导致堆损坏