损坏的堆 - C

发布于 2024-11-26 13:31:45 字数 7791 浏览 1 评论 0原文

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

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

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

然后它出现了中断/继续。

该代码使用 Gauss-Siedel 迭代方法来求解 xn 线性方程组。在本例中,我需要找到 3 个人(A、B、C)所连接的 3 根串联弹力绳的总拉伸量 (X)。每个解决方案都有不同的附加人员排列(即 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"
 */

I keep getting the following error message when I run my code in debug.

Windows has triggered a breakpoint in Linear Equations 331.exe.

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

Then it comes up with a break/continue.

The code uses a Gauss-Siedel Iterative method to solve a n x n system of linear equations. In this case I need to find the total amount of stretch (X) for 3 bungee cords in series,with 3 people (A,B,C) attached to it. Each solution has a different permutation of the people attached (i.e. A,B,C ; A,C,B ; B,A,C etc.)

We were supplied with a memory allocation header file called alloc.h, though I don't fully understand how it works which may be causing my problem. It worked fine before I started using ALLOCATE() for more variables. Any help in explaining why this is happening would be really helpful.

The main code is first. Header Files are at the bottom. Sorry if the code is a bit messy. I tried to comment as best as I could:

#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"
 */

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦忆晨望 2024-12-03 13:31:45

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

请注意该地址,在调试器中重新启动程序,在分配发生后设置断点,然后在该内存位置上设置数据断点并运行以查看谁正在破坏它。

When his error occurs in the debugger, it should tell you where you are in the program that it occurs - hopefully this will let you identify which memory location is being corrupted.

Note that address, restart the program in the debugger, set a breakpoint for after the allocations occurs, then set a data breakpoint on that memory location and run to see who's trashing it.

你是暖光i 2024-12-03 13:31:45

如果用于链接项目的运行时库与库的不同,则 dll 可能会导致堆损坏

dlls may cause heap corruption if the runtime library for linking of your project differs from the library's

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文