Search code examples
c++xcodesegmentation-faultprogram-entry-pointexc-bad-access

Failed to generate disassembly for stack frame because the URL cannot be translated & Segmentation fault: 11


I am still a newbie in programming. I am writing a program of 2D Snell's Law. I know the problem may due to wrong localisations in Xcode, but I am writing in C++ only and g++ even gives me segmentation fault error after compiling successfully.

Here are my code for main function:

#include <string>

#include "Snell.hpp"

int main(int argc, const char * argv[]){//thread 1 exc_bad_access (code=2 address=0x7fff5f238304)
    string filename;
    double time;
    Snell S[3600];

    for (int i=1; i<=1; i++) {
        while (S[i].angle_tr>0) {
            filename="VPVSMOD"+to_string(i)+".txt";
            S[i].Open(filename);
            time=S[i].Locate(i);
            cout<<"The "<<i<<"th event takes "<<time<<" seconds to reach the destination"<<endl;
            S[i].angle_tr-=0.01;
        }
    }

    return 0;
}

Here is the code for Snell.hpp

#ifndef Snell_hpp
#define Snell_hpp

#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <string>
#include <algorithm>
#include <cmath>

using namespace std;

class Snell{
private:
    double GetV(double lat,double dep);
    int ny,nz,time;
    double la[30],h[20],v[10][30];
    double lat,alt,step;
public:
    Snell();
    void Open(string filename);
    double Locate(int i);
    double angle_tr;
};

#endif /* Snell_hpp */

and Snell.cpp:

#include "Snell.hpp"

Snell::Snell(){
    ny=1,nz=3,time=0;
    lat=0,alt=0,step=1;
    angle_tr=M_PI/2;
}

void Snell::Open(string filename){
    ifstream fin(filename);
    stringstream ss;
    string str,tok;

    for (int i=0; i<nz; i++) {
        (getline(fin, str));
        ss.str(str);
        for (int j=0; j<ny; j++) {
            getline(ss, tok, ',');
            v[i][j]=stod(tok);
            cout<<v[i][j]<<",i="<<i<<",j="<<j<<endl;
        }
        ss.clear();
    }

    fin.close();
    angle_tr=v[1][0]/v[0][0];
}

double Snell::GetV(double lat, double dep){
    int index_la = 0,index_dep = 0;

    index_dep=round(dep);
    return (v[index_dep][index_la]+v[index_dep+1][index_la])/2;
}

double Snell::Locate(int i){
    string filename;
    double count_t=0;
    double latt=lat,altt=alt,step_altt_all=0,angle=0,angle_p=0;
    double vsy,vsz;
    double vs,vs_n;
    ofstream fout;
        angle=M_PI/2-atan(angle_tr);
        vs=GetV(lat, alt);

        filename="Test"+to_string(i)+"_"+to_string(time)+".txt";
        fout.open(filename,ios::out);
        fout<<lat<<","<<alt<<endl;

        while (altt!=2) {
            //cout<<"Compute Velocity in each dimension"<<endl;
            angle_p=angle;
            vsy=vs*cos(angle);
            vsz=vs*sin(angle);
            //cout<<"Check Velocity"<<endl;
            if (vsy==0||vsz==0) {
                break;
            }

            //cout<<"Compute reflection point"<<endl;
            step_altt_all=step/vsz;
            count_t=count_t+step/vsz;//time plus one
            latt=latt+vsy*(step_altt_all);
            step_altt_all=0;
            altt=altt+step;

            //cout<<"Compute New Velocity"<<endl;    
            vs_n=GetV(latt,altt);
            if ((vs_n*cos(angle)/vs)>1) {
                break;
            }
            else{
                angle=M_PI/2-asin(vs_n*cos(angle)/vs);
                vs=vs_n;
                if (angle!=angle_p)
                    fout<</*"position:"<<*/latt<<","<<altt<<endl;
            }
        }

        fout.close();
        filename="Result"+to_string(i)+"_"+to_string(time)+".txt";
        fout.open(filename);
        fout<<0<<" "<<latt<<" "<<altt<<" "<<step<<endl;
        fout.close();
        return count_t;
}

Solution

  • My immediate guess is: You must have blown your stack. Please see why is stack memory size so limited?

    ....And yes, On my platform, my guess was correct...

    Reproducing your program, but modifying your main.cpp ...

    int main(int argc, const char * argv[]){//thread 1 exc_bad_access (code=2 address=0x7fff5f238304)
        string filename;
        double time;
        //Snell S[3600];
        std::cout << sizeof(Snell) << " bytes" << std::endl;
    
        return 0;
    }
    

    It gives an output of

    2848 bytes
    

    ....And You are trying to allocate 3600 of them... ~10MB!! The solution to that is to allocate it on the heap using a std::unique_ptr or better still, your good friend, std::vector.

    Modify your main to this

    #include <string>
    #include <memory>
    //or #include <vector>
    
    #include "Snell.hpp"
    
    int main(int argc, const char * argv[]){//thread 1 exc_bad_access (code=2 address=0x7fff5f238304)
        string filename;
        double time;
        std::unique_ptr<S[]> p(new Snell[3600]);
        //or std::vector<Snell> S(3600);
    
        for (int i=1; i<=1; i++) {
            while (S[i].angle_tr>0) {
                filename="VPVSMOD"+to_string(i)+".txt";
                S[i].Open(filename);
                time=S[i].Locate(i);
                cout<<"The "<<i<<"th event takes "<<time<<" seconds to reach the destination"<<endl;
                S[i].angle_tr-=0.01;
            }
        }
    
        return 0;
    }