Thread: C code with multiple arrays gives Seg Fault Error

  1. #1
    Registered User
    Join Date
    Dec 2014
    Location
    Milwaukee
    Posts
    1

    C code with multiple arrays gives Seg Fault Error

    I am looking for some troubleshooting help. I am working on a code that uses a finite method for simulating a fluids problem. I have defined my 2D flow domain using multiple arrays. The arrays can be scaled by a dimensionless variable (D). When I run my code, I am given an error popup window that says that the program has stopped running. My compiler ide mentions a seg fault, however, I can not seem to figure out how to correct this. Any help would be appreciated.
    Here's my code:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #define D 6
    #define H 3*D
    #define L 35*D
    #define M 0.05
    #define Re 20.0
    #define Sig 0.9
    #define RhoNot 1.0
    #define dx 1.0
    #define dt (Sig/sqrt(2))*M*dx      /*Time step calculated as a function of safety factor (pg. 432), Mach number, and x interval. Source: Kundu, Fluid Mechanics, 5th Edition, Pg. 447, Eq. 11.155 */
    #define t 10
    #define U 1.0
    #define BoxFront 15*D
    #define BoxBack 15*D+D-1
    #define BoxTop 2*D
    #define BoxBottom D
    #define a1 (dt/dx)
    #define a2 a1
    #define a3 (dt/(dx*M*M))
    #define a4  a3
    #define a5  (4*dt/(3*Re*dx*dx))
    #define a6  (dt/(Re*dx*dx))
    #define a7  a6
    #define a8  a5
    #define a9  (dt/(12*Re*dx*dx))
    #define a10 2*(a5+a6)
    #define a11 2*(a7+a8)
    
    
    struct Flow_Domain {
        double u[H][L];
        double v[H][L];
        double rho[H][L];
        double rhou[H][L];
        double rhov[H][L];
    };
    
    
    void Calc_Vel(struct Flow_Domain *Vel);
    void Calc_Dens(struct Flow_Domain *corr, struct Flow_Domain *pred, int step);
    void Bound_Cond(struct Flow_Domain *pred);
    
    
    int main()
    {
        int i,j,step,m,w=0;
        int numfiles=1;
        struct Flow_Domain pred;
        struct Flow_Domain corr;
        FILE *u_vel[numfiles],*v_vel[numfiles];
    
    
        /*Initial Conditions*/
        for (i=0; i<H; i++){
            for (j=0; j<L; j++){
                    if (((i<BoxBottom||i>BoxTop))||(j<BoxFront||j>BoxBack)){
                        corr.rho[i][j]=RhoNot;
                        corr.u[i][j]=U;
                        corr.v[i][j]=0;
                        corr.rhou[i][j]=corr.rho[i][j]*corr.u[i][j];
                        corr.rhov[i][j]=corr.rho[i][j]*corr.v[i][j];
                    }
                    else{
                        corr.rho[i][j]=RhoNot;
                        corr.u[i][j]=0;
                        corr.v[i][j]=0;
                        corr.rhou[i][j]=0;
                        corr.rhov[i][j]=0;
                    }
                    if((i==(BoxBottom-1)&&j<=BoxBack+1&&j>=BoxFront-1)||(i==BoxTop&&j<=BoxBack+1&&j>=BoxFront-1)||(j==BoxFront-1&&i>=BoxBottom-1&&i<BoxTop+1)||(j==BoxBack+1&&i>=BoxBottom-1&&i<BoxTop+1)){
                        corr.u[i][j]=0;
                        corr.v[i][j]=0;
                    }
            }
        }
        for (m=0; m<=t;m++){
            step=1;
            Calc_Vel(&corr);
            step=2;
            Calc_Dens(&corr,&pred,step);
            step=3;
            Bound_Cond(&pred);
            step=4;
            Calc_Vel(&pred);
            step=5;
            Calc_Dens(&pred,&corr,step);
            step=6;
            Bound_Cond(&corr);
    
    
            if (m>(t-numfiles)){                                                     /*Save several time steps worth of data and export as text files*/
                char uname[20];
                sprintf(uname,"U_%d.txt",m);
                u_vel[w]=fopen(uname,"w");
                for(i=0;i<H;i++){
                    for(j=0;j<L;j++){
                        if(j<(L)){
                            fprintf(u_vel[w], "%f ", corr.u[i][j]);
                        }
                        if(j==(L-1)){
                            fprintf(u_vel[w],"\n");
                        }
                    }
                }
                fclose(u_vel[w]);
                char vname[20];
                sprintf(vname,"V_%d.txt",m);
                v_vel[w]=fopen(vname,"w");
                for(i=0;i<H;i++){
                    for(j=0;j<L;j++){
                        if(j<(L)){
                            fprintf(v_vel[w], "%f ", corr.v[i][j]);
                        }
                        if(j==(L-1)){
                            fprintf(v_vel[w],"\n");
                        }
                    }
                }
                fclose(v_vel[w]);
            }
        }
    
    
    
    
        return 0;
    }
    
    
    void Calc_Vel(struct Flow_Domain *Vel){
        int i=0,j=0;
        for (i=0; i<H; i++){
            for (j=0; j<L; j++){
                    if (((i<BoxBottom||i>BoxTop))||(j<BoxFront||j>BoxBack)){
                        Vel->u[i][j]=Vel->rhou[i][j]/Vel->rho[i][j];
                        Vel->v[i][j]=Vel->rhov[i][j]/Vel->rho[i][j];
                    }
            }
        }
    }
    
    
    
    
    void Calc_Dens(struct Flow_Domain *corr, struct Flow_Domain *pred, int step){
        int m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14,m15,m16,m17,m18,m19,m20,m21,m22;
        int n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22;
        int sw,i,j;
        double a,b;
        for (i=1; i<H-1; i++){
                for(j=1; j<L-1; j++){
                        if(j==(BoxFront-1)&&i<=BoxTop&&i>=BoxBottom){
                            sw=1;
                            m1=i-1, m2=i-2, m3=i-1, m4=i-2, m5=i-3, m6=i-2, m7=i-2, m8=i-1, m9=i-1, m10=i, m11=i;
                            n1=j, n2=j, n3=j, n4=j, n5=j, n6=j+1, n7=j-1, n8=j+1, n9=j-1, n10=j+1, n11=j-1;
                        }
                        else if(j==(BoxBack+1)&&i<=BoxTop&&i>=BoxBottom){
                            sw=1;
                            m1=i+1, m2=i+2, m3=i+1, m4=i+2, m5=i+3, m6=i+2, m7=i+2, m8=i+1, m9=i+1, m10=i, m11=i;
                            n1=j, n2=j, n3=j, n4=j, n5=j, n6=j+1, n7=j-1, n8=j+1, n9=j-1, n10=j+1, n11=j-1;
                        }
                        else if(i==(BoxTop+1)&&j>=BoxFront&&j<=BoxBack){
                            sw=1;
                            n1=j+1, n2=j+2, n3=j+1, n4=j+2, n5=j+3, n6=j+2, n7=j+2, n8=j+1, n9=j+1, n10=j, n11=j;
                            m1=i, m2=i, m3=i, m4=i, m5=i, m6=i+1, m7=i-1, m8=i+1, m9=i-1, m10=i+1, m11=i-1;
                        }
                        else if(i==(BoxBottom-1)&&j>=BoxFront&&j<=BoxBack){
                            sw=1;
                            n1=j-1, n2=j-2, n3=j-1, n4=j-2, n5=j-3, n6=j-2, n7=j-2, n8=j-1, n9=j-1, n10=j, n11=j;
                            m1=i, m2=i, m3=i, m4=i, m5=i, m6=i+1, m7=i-1, m8=i+1, m9=i-1, m10=i+1, m11=i-1;
                        }
                        else if(i==(BoxBottom-1)&&j==(BoxFront-1)){
                            sw=2;
                            n1=j-1, n2=j-2, n3=j-1, n4=j-2, n5=j-3, n6=j-2, n7=j-2, n8=j-1, n9=j-1, n10=j, n11=j;
                            m1=i, m2=i, m3=i, m4=i, m5=i, m6=i+1, m7=i-1, m8=i+1, m9=i-1, m10=i+1, m11=i-1;
                            m12=i-1, m13=i-2, m14=i-1, m15=i-2, m16=i-3, m17=i-2, m18=i-2, m19=i-1, m20=i-1, m21=i, m22=i;
                            n12=j, n13=j, n14=j, n15=j, n16=j, n17=j+1, n18=j-1, n19=j+1, n20=j-1, n21=j+1, n22=j-1;
                        }
                        else if(i==(BoxBottom-1)&&j==(BoxBack+1)){
                            sw=2;
                            n1=j-1, n2=j-2, n3=j-1, n4=j-2, n5=j-3, n6=j-2, n7=j-2, n8=j-1, n9=j-1, n10=j, n11=j;
                            m1=i, m2=i, m3=i, m4=i, m5=i, m6=i+1, m7=i-1, m8=i+1, m9=i-1, m10=i+1, m11=i-1;
                            m12=i+1, m13=i+2, m14=i+1, m15=i+2, m16=i+3, m17=i+2, m18=i+2, m19=i+1, m20=i+1, m21=i, m22=i;
                            n12=j, n13=j, n14=j, n15=j, n16=j, n17=j+1, n18=j-1, n19=j+1, n20=j-1, n21=j+1, n22=j-1;
                        }
                        else if(i==(BoxTop+1)&&j==(BoxFront-1)){
                            sw=2;
                            n1=j+1, n2=j+2, n3=j+1, n4=j+2, n5=j+3, n6=j+2, n7=j+2, n8=j+1, n9=j+1, n10=j, n11=j;
                            m1=i, m2=i, m3=i, m4=i, m5=i, m6=i+1, m7=i-1, m8=i+1, m9=i-1, m10=i+1, m11=i-1;
                            m12=i-1, m13=i-2, m14=i-1, m15=i-2, m16=i-3, m17=i-2, m18=i-2, m19=i-1, m20=i-1, m21=i, m22=i;
                            n12=j, n13=j, n14=j, n15=j, n16=j, n17=j+1, n18=j-1, n19=j+1, n20=j-1, n21=j+1, n22=j-1;
                        }
                        else if(i==(BoxTop+1)&&j==(BoxBack+1)){
                            sw=2;
                            n1=j+1, n2=j+2, n3=j+1, n4=j+2, n5=j+3, n6=j+2, n7=j+2, n8=j+1, n9=j+1, n10=j, n11=j;
                            m1=i, m2=i, m3=i, m4=i, m5=i, m6=i+1, m7=i-1, m8=i+1, m9=i-1, m10=i+1, m11=i-1;
                            m12=i+1, m13=i+2, m14=i+1, m15=i+2, m16=i+3, m17=i+2, m18=i+2, m19=i+1, m20=i+1, m21=i, m22=i;
                            n12=j, n13=j, n14=j, n15=j, n16=j, n17=j+1, n18=j-1, n19=j+1, n20=j-1, n21=j+1, n22=j-1;
                        }
                        else {
                            if(step==2){
                                pred->rho[i][j]=corr->rho[i][j]-a1*(corr->rhou[i+1][j]-corr->rhou[i][j])-a2*(corr->rhov[i][j+1]-corr->rhov[i][j]);
                                pred->rhou[i][j]=corr->rhou[i][j]-a3*(corr->rho[i+1][j]-corr->rho[i][j])-a1*((corr->rho[i+1][j]*corr->u[i+1][j]*corr->u[i+1][j])-(corr->rho[i][j]*corr->u[i][j]*corr->u[i][j]))-a2*(corr->rhou[i][j+1]*corr->v[i][j+1]-corr->rhou[i][j]*corr->v[i][j])-a10*corr->u[i][j]+a5*(corr->u[i+1][j]+corr->u[i-1][j])+a6*(corr->u[i][j+1]+corr->u[i][j-1])+a9*(corr->v[i+1][j+1]+corr->v[i-1][j-1]-corr->v[i+1][j-1]-corr->v[i-1][j+1]);
                                pred->rhov[i][j]=corr->rhov[i][j]-a4*(corr->rho[i][j+1]-corr->rho[i][j])-a1*(corr->rhou[i+1][j]*corr->v[i+1][j]-corr->rhou[i][j]*corr->v[i][j])-a2*((corr->rho[i][j+1]*corr->v[i][j+1]*corr->v[i][j+1])-(corr->rho[i][j]*corr->v[i][j]*corr->v[i][j]))-a11*corr->v[i][j]+a7*(corr->v[i+1][j]+corr->v[i-1][j])+a8*(corr->v[i][j+1]+corr->v[i][j-1])+a9*(corr->u[i+1][j+1]+corr->u[i-1][j-1]-corr->u[i+1][j-1]-corr->u[i-1][j+1]);
                            }
                            if(step==5){
                                pred->rho[i][j]=(pred->rho[i][j]+corr->rho[i][j])-a1*(corr->rhou[i][j]-corr->rhou[i-1][j])-a2*(corr->rhov[i][j]-corr->rhov[i][j-1]);
                                pred->rho[i][j]=pred->rho[i][j]/2.0;
                                pred->rhou[i][j]=(pred->rhou[i][j]+corr->rhou[i][j])-a3*(corr->rho[i][j]-corr->rho[i-1][j])-a1*((corr->rho[i][j]*corr->u[i][j]*corr->u[i][j])-(corr->rho[i-1][j]*corr->u[i-1][j]*corr->u[i-1][j]))-a2*(corr->rhou[i][j]*corr->v[i][j]-corr->rhou[i][j-1]*corr->v[i][j-1])-a10*corr->u[i][j]+a5*(corr->u[i+1][j]+corr->u[i-1][j])+a6*(corr->u[i][j+1]+corr->u[i][j-1])+a9*(corr->v[i+1][j+1]+corr->v[i-1][j-1]-corr->v[i+1][j-1]-corr->v[i-1][j+1]);
                                pred->rhou[i][j]=pred->rhou[i][j]/2.0;
                                pred->rhov[i][j]=(pred->rhov[i][j]+corr->rhov[i][j])-a4*(corr->rho[i][j]-corr->rho[i][j-1])-a1*(corr->rhou[i][j]*corr->v[i][j]-corr->rhou[i-1][j]*corr->v[i-1][j])-a2*((corr->rho[i][j]*corr->v[i][j]*corr->v[i][j])-(corr->rho[i][j-1]*corr->v[i][j-1]*corr->v[i][j-1]))-a11*corr->v[i][j]+a7*(corr->v[i+1][j]+corr->v[i-1][j])+a8*(corr->v[i][j+1]+corr->v[i][j-1])+a9*(corr->u[i+1][j+1]+corr->u[i-1][j-1]-corr->u[i+1][j-1]-corr->u[i-1][j+1]);
                                pred->rhov[i][j]=pred->rhov[i][j]/2.0;
                            }
    
    
                        }
    
    
                        if(sw==1){
                                pred->rho[i][j]=(1.0/3.0)*(4.0*corr->rho[m1][n1]-corr->rho[m2][n2])+(8.0/(9.0*dx))*((M*M)/Re)*(-5.0*corr->u[m3][n3]+4.0*corr->u[m4][n4]-corr->u[m5][n5])-(1.0/(18.0*dx))*((M*M)/Re)*(-(corr->v[m6][n6]-corr->v[m7][n7])+(4.0*(corr->v[m8][n8]-corr->v[m9][n9]))-3.0*(corr->v[m10][n10]-corr->v[m11][n11]));
                        }
                        if(sw==2){
                                a=(1.0/3.0)*(4.0*corr->rho[m1][n1]-corr->rho[m2][n2])+(8.0/(9.0*dx))*((M*M)/Re)*(-5.0*corr->u[m3][n3]+4.0*corr->u[m4][n4]-corr->u[m5][n5])-(1.0/(18.0*dx))*((M*M)/Re)*(-(corr->v[m6][n6]-corr->v[m7][n7])+(4.0*(corr->v[m8][n8]-corr->v[m9][n9]))-3.0*(corr->v[m10][n10]-corr->v[m11][n11]));
                                b=(1.0/3.0)*(4.0*corr->rho[m12][n12]-corr->rho[m13][n13])+(8.0/(9.0*dx))*((M*M)/Re)*(-5.0*corr->u[m14][n14]+4.0*corr->u[m15][n15]-corr->u[m16][n16])-(1.0/(18.0*dx))*((M*M)/Re)*(-(corr->v[m17][n17]-corr->v[m18][n18])+(4.0*(corr->v[m19][n19]-corr->v[m20][n20]))-3.0*(corr->v[m21][n21]-corr->v[m22][n22]));
                                pred->rho[i][j]=(a+b)/2.0;
                        }
                }
        }
    }
    
    
    void Bound_Cond(struct Flow_Domain *pred){
        int i,j;
        for (i=0; i<H; i++){
            for (j=0; j<L; j++){
                    if (((i<BoxBottom||i>BoxTop))||(j<BoxFront||j>BoxBack)){
                        pred->rho[i][j]=RhoNot;
                        pred->u[i][j]=U;
                        pred->v[i][j]=0;
                        pred->rhou[i][j]=pred->rho[i][j]*pred->u[i][j];
                        pred->rhov[i][j]=pred->rho[i][j]*pred->v[i][j];
                    }
                    else{
                        pred->rho[i][j]=RhoNot;
                        pred->u[i][j]=0;
                        pred->v[i][j]=0;
                        pred->rhou[i][j]=0;
                        pred->rhov[i][j]=0;
                    }
                    if((i==(BoxBottom-1)&&j<=BoxBack+1&&j>=BoxFront-1)||(i==BoxTop+1&&j<=BoxBack+1&&j>=BoxFront-1)||(j==BoxFront-1&&i>=BoxBottom-1&&i<BoxTop+1)||(j==BoxBack+1&&i>=BoxBottom-1&&i<BoxTop+1)){
                        pred->u[i][j]=0;
                        pred->v[i][j]=0;
                    }
                    if(j==(L-1)){
                        pred->rho[i][j]= pred->rho[i][j-1];
                        pred->rhou[i][j]= pred->rhou[i][j-1];
                        pred->rhou[i][j]= pred->rhou[i][j-1];
                    }
            }
        }
    }

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,907
    I ran your program and nothing happened (that I could see): no crash/seg fault, no output, no chance for input. It would help if you told us how to run your program, specifically what input you give that causes the seg fault. It's a lot of dense code, with no usage/help message or comments that describe anything about running it.

    I would bet somewhere you have an array out of bounds. Exactly where is hard to tell. Probably has something to do with your calculations of n or m based on BoxTop, BoxBottom, etc. If you ran the code through a debugger, it would almost certainly find the offending array access, and you could backtrace and examine variables, or step up to that point line by line, and watch what piece of code originally caused it.

    Some general notes:

    • In a complex program like this, having clear, well-organized code is paramount, to avoid any small mistakes that are easily lost amongst the complicated mathematical code. If it's hard to read, it's easy to make mistakes and hard to find or fix them.
    • Use lots of comments that explain the calculation in "plain English", that is, an easy way to see what you intended the code to do, so one can see if the code actually does that, or if it does something else.
    • Keep your lines short. 80 chars wide is pretty standard, up to 120 is fairly widely accepted. Beyond that, it's too difficult to keep track of what you're doing. 455 is just absurd.
    • To help with the above: use temporary variables to calculate sub-parts of long expressions.
    • Also, break your lines in logical places (there's no rule that a line must include the full expression up to the semicolon). Typically on operators is good, and keeping parentheses levels in mind when you indent continuing lines is also helpful.
    • Put some bloody spaces around your operators. There's way too many small variable names and punctuation to clearly read what any statement does.
    • Make sure you know your operator precedence. I see come comparisons and other calculations that maybe should have a few extra parentheses just to ensure everything is happening in the right order.
    • There's no need to use the comma operator to put multiple assignments on a single line. Just separate them with a semicolon. Except...
    • Whenever you see yourself naming variables with numerical suffixes, think arrays. n1...n20 should be int n[22]; (except 22 should be a define with a descriptive name). See below
    • When you see similar code in multiple block (e.g. if statements lines 154-201), look for ways to reuse that. Parameterize it and put it into a function. Then there's only one place to make, find and fix errors. Once it works, you can leave it alone; every time you call it, you will know it just works.
    • You do this weird step=1; step=2; thing, and only use step in Calc_Dens, and only when it has one of two values. Instead of arbitrary magic numbers like 2 and 5 (the values 2 and 5 are irrelevant), just define an enum with two elements, with names that make sense. See below


    I realize making n and m arrays may be difficult. Some ideas:
    You can have an array of n_j_offsets to add to j, so n[i] = j + n_j_offsets[i] where n_j_offsets[22] = {1, 2, 1, 2, 3, ..., -1, 1, -1}; You can have multiple n_j_offsets, perhaps each with their own appropriate name. Then, it's an easy loop to update all the values of n/m each time, to the correct values
    Consider a 2-d array for n and m, where each "row" corresponds to a different if condition on lines 154-201, and each column to n1, n2, ....
    Code:
    enum DensityStep {
        DENSITY_STEP_FOO,
        DENSITY_STEP_BAR,
    };
    ...
    Calc_Density(&corr, &pred, DENSITY_STEP_FOO);
    Bound_Cond(&pred);
    Calc_Vel(&pred);
    Calc_Density(&pred, &corr, DENSITY_STEP_BAR);
    ...
    void Calc_Density(struct Flow_Domain *corr, struct Flow_Domain *pred, enum DensityStep step){
    if (step == DENSITY_STEP_FOO) {
    } else if (step == DENSITY_STEP_BAR)
    Notice I took the liberty of explicitly stating "density" instead of "dens". I assume that what dens is short for, but I really don't know. Never sacrifice clarity to sav e a few keystrokes.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Code::Blocks error multiple definition of 'main'
    By amber18 in forum C++ Programming
    Replies: 7
    Last Post: 07-05-2013, 02:13 PM
  2. Why this code gives a segmentation fault error?
    By xianwen in forum C Programming
    Replies: 2
    Last Post: 11-13-2011, 08:09 PM
  3. Seg Fault AND 2d dynamic arrays
    By lord in forum C++ Programming
    Replies: 3
    Last Post: 08-04-2008, 01:07 PM
  4. Replies: 2
    Last Post: 02-23-2004, 06:34 AM
  5. Parallel Arrays with Multiple Arrays
    By Billye Scott in forum C++ Programming
    Replies: 0
    Last Post: 03-02-2002, 11:14 PM

Tags for this Thread