在调试中运行代码时,我不断收到以下错误消息。
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"
*/
答案 0 :(得分:0)
当他在调试器中发生错误时,它应该告诉你它在程序中的位置 - 希望这可以让你识别哪个内存位置被破坏了。
注意地址,在调试器中重新启动程序,在分配发生后设置断点,然后在该内存位置设置一个数据断点并运行以查看谁将其丢弃。
答案 1 :(得分:0)