Dear all,

I'm a C++ beginner and I'm facing a problem with C++ program running on Dev C++ 4.9.9.2. The following program builds and compiles just fine however when I try to execute it it stops before getting any output. Actually the line causing the problem might be the "y_pos[][]" array definition line but I don't know why!!! I just get the following when the debugger reaches this line:

An Access violation (Segmentation fault) is raised in the program.

The code:

#include<math.h>
#include<cstdlib>
#include<stdio.h>
#include<iostream>
#include<fstream>
#include<string.h>

using namespace std;


#define TM 0
#define Di 1
#define Nsteps 40000
#define pi 3.14159265
                


#define courant_factor 1
#define nwave 20
#define dx 0.00001
#define dy 0.00001

int main()
{    


float c;
float etao;     
float dt;

char boundarytype_xn = 'p';
int boundaryair_buffer_number_of_cells_xn = 160;
int boundarypml_number_of_cells_xn = 15;

char boundarytype_xp = 'p';
int boundaryair_buffer_number_of_cells_xp = 160;
int boundarypml_number_of_cells_xp = 15;

char boundarytype_yn = 'p';
int boundaryair_buffer_number_of_cells_yn = 160;
int boundarypml_number_of_cells_yn = 15;

char boundarytype_yp = 'p';
int boundaryair_buffer_number_of_cells_yp = 160;
int boundarypml_number_of_cells_yp = 15;

int boundarypml_order = 2;
float boundarypml_R_0 = 1e-8;

float matter_typeser [2];
float matter_typesmr [2];
float matter_typesse [2];
float matter_typessm [2];
float t_er[2];
float t_mr[2];
float t_se[2];
float t_sm[2];
float time[Nsteps];
int incident_waveE_theta,incident_waveE_phi;
float incident_wavetheta_incident,incident_wavephi_incident;
char incident_wavewaveform_type;
float frequency_domainstart;
float frequency_domainend;
float frequency_domainstep;
float V;
float sampledx;
float sampledy;
char sampledcomponent;
bool sampleddisplay_plot;
bool draw_domainenable;
bool draw_domaindraw_axis;
bool draw_domaindraw_grid;
bool is_pml_xp;
bool is_pml_xn;
bool is_pml_yp;
bool is_pml_yn;
bool is_any_side_pml;
int n_pml_xn;
int n_pml_xp;
int n_pml_yn;
int n_pml_yp;
int number_of_circles;
int number_of_objects;
float min_x;
float min_y;
float max_x;
float max_y;
float fxx_domainmin_x;
float fxx_domainmin_y;
float fxx_domainmax_x;
float fxx_domainmax_y;
float fxx_domainsize_x;
float fxx_domainsize_y;
int ind;
int ind2;
float theta_incident;
float phi_incident;
float E_theta;
float E_phi;
float Exi0,Eyi0,Ezi0,Hxi0,Hyi0,Hzi0;


float circlescenter_x = 0.04;
float circlescenter_y = 0.05;
float circlesradius   = 0.00075;
int circlesmaterial_type = 2;
float measurept=0.0015;
float measureangle=0; 


matter_typeser [0]=1.0; 
if(Di==1)
matter_typeser [1]= 22.39;
else
matter_typeser [1]= 1.0;
matter_typesmr [0] = 1.0; 
matter_typesmr [1]=1.0;
matter_typesse [0]=0.0;
if(Di==1) 
matter_typesse [1]=53.73;
else
matter_typesse [1]=10000000000.0;
matter_typessm [0]=0.0;
matter_typessm [1]=0.0; 

// Define incident wave, angles are in degrees
if(TM==1)
 {incident_waveE_theta= 1;
  incident_waveE_phi  = 0;}
else
 {incident_waveE_theta = 0;
  incident_waveE_phi   = 1;}

incident_wavetheta_incident = 90;
incident_wavephi_incident = 0;
incident_wavewaveform_type = 'g';

// frequency domain parameters
frequency_domainstart = 30e9;
frequency_domainend   = 60e9;
frequency_domainstep  = 0.5e9;


V=measureangle+180;
sampledx = circlescenter_x+(circlesradius+measurept)*cos((V*pi)/180.0);
sampledy = circlescenter_y+(circlesradius+measurept)*sin((V*pi)/180.0);
if(TM==1)
sampledcomponent = 'z';
else
sampledcomponent = 'm';

sampleddisplay_plot = false;

draw_domainenable = true;
draw_domaindraw_axis = false;
draw_domaindraw_grid = false;


is_pml_xn = true;
is_pml_xp = true;
is_pml_yn = true;
is_pml_yp = true;
is_any_side_pml = true;
n_pml_xn = boundarypml_number_of_cells_xn;
n_pml_xp = boundarypml_number_of_cells_xp;
n_pml_yn = boundarypml_number_of_cells_yn;
n_pml_yp = boundarypml_number_of_cells_yp;
    

number_of_circles = 1;

    number_of_objects = 1;
    min_x = circlescenter_x - circlesradius; 
    min_y = circlescenter_y - circlesradius; 
    max_x = circlescenter_x + circlesradius; 
    max_y = circlescenter_y + circlesradius; 

if (number_of_objects == 0)
   {fxx_domainmin_x = 0;
    fxx_domainmin_y = 0;
    fxx_domainmax_x = 0;
    fxx_domainmax_y = 0;}
else
   {fxx_domainmin_x = min_x;
    fxx_domainmin_y = min_y;
    fxx_domainmax_x = max_x;
    fxx_domainmax_y = max_y;}

// Determine the problem space boundaries including air buffers 
fxx_domainmin_x = fxx_domainmin_x - dx * (boundaryair_buffer_number_of_cells_xn + n_pml_xn);
fxx_domainmin_y = fxx_domainmin_y - dy * (boundaryair_buffer_number_of_cells_yn + n_pml_yn);
fxx_domainmax_x = fxx_domainmax_x + dx * (boundaryair_buffer_number_of_cells_xp + n_pml_xp);
fxx_domainmax_y = fxx_domainmax_y + dy * (boundaryair_buffer_number_of_cells_yp + n_pml_yp);

// Determining the problem space size
fxx_domainsize_x = fxx_domainmax_x - fxx_domainmin_x;
fxx_domainsize_y = fxx_domainmax_y - fxx_domainmin_y;

// number of cells in x, y, and z directions
int nx=static_cast<int>(round(fxx_domainsize_x/dx));
int ny=static_cast<int>(round(fxx_domainsize_y/dy));
int nxp1=nx+1;
int nxm1=nx-1;
int nxm2=nx-2;
int nyp1=ny+1;
int nym1=ny-1;
int nym2=ny-2;


fxx_domainsize_x = nx * dx;
fxx_domainsize_y = ny * dy;

fxx_domainmax_x = fxx_domainmin_x + fxx_domainsize_x;
fxx_domainmax_y = fxx_domainmin_y + fxx_domainsize_y;


float x_pos[nxp1][nyp1];
float y_pos[nxp1][nyp1];
for(ind=0;ind<nxp1;ind++)
for(ind2=0;ind2<nyp1;ind2++)
{
x_pos[ind][ind2]=0.0;
y_pos[ind][ind2]=0.0;
}

float cx[nx][ny];
float cy[nx][ny];
int matter_2d[nx][ny];

for(ind=0;ind<nx;ind++)
for(ind2=0;ind2<ny;ind2++)
{
cx[ind][ind2]=0.0;
cy[ind][ind2]=0.0;
matter_2d[ind][ind2]=1;
}
cin.get();
return 0;
}

Edited 4 Years Ago by johnnydarten: n/a

>> The following program builds and compiles just fine

I'm a little surprised at that. You have array sizes that appear to be based on variables(i.e. unknown at compile time). I haven't worked my way through the program to see if these sizes will always be the same when they hit the array declaration. If so, the compiler might substitute a constant in there.


Regarding the access violation error, you need to find out exactly what line it's happening at. There are a few techniques to do that if you aren't told where it is at runtime. One, sprinkle a bunch of print statements around the program. Try to see where it stops printing. For example, in the following program...

#include <iostream>
using namespace std;
int main()
{
    int a[5];
    cout << "Hello world 1\n";
    a[5] = 9; // seg fault.  5 is an illegal index
    cout << "Hello world 2\n";
    return 0;
}

There is a seg fault on line 7. "Hello World 1" will print, but not "Hello World 2". That gives a clue that the seg fault is BETWEEN those two statements. The downside is that very often, the compiler will set aside MORE than the size of the array you asked it to or at least if it doesn't, that address will still be accessible so both will print. It's not a surefire method, but sometimes it works.

Similarly, if you run it in an IDE like Dev C++, the IDE might tell you exactly where the Seg Fault is. It might not. You can also use an assert statement to check variable values.

#include <iostream>
#include <cassert>
using namespace std;
int main()
{
    int a[5];
    int index = 5;
    cout << "Hello world 1\n";
    assert(index < 5); // valid indexes are less than 5.
    a[index] = 9; // seg fault.  5 is an illegal index
    cout << "Hello world 2\n";
    return 0;
}

In this case, it will definitely fail and will give you the exact line number...

Hello world 1
Assertion failed: index < 5, file dani.cpp, line 9

You can also use the debugger and breakpoints in Dev C++ to "step through" the program line by line. When it crashes, you know the last line that worked.

The point is that you need to somehow narrow it down a bit. You need to know what the allowable indexes are for each array and make sure that you aren't outside of that range. Any "variable" that doesn't vary should be turned into a constant to make for easier debugging.

Since you are a beginner, I would go with my first suggestion. Sprinkle a bunch of "Hello World" lines in the code and see how far you get. That'll help narrow it down. Once you find it, print the value of the variable that you are using as an index in the array and make sure it's good. Seg faults can be extremely difficult to nail down. It's more of an art than am science.

Dear VernonDozier,

Actually the size of array needs to be computed at runtime. Another point is that I already debugged the program and as i said the fault is at line 217-218 where I define the arrays x_pos[nxp1][nyp1] and y_pos[nxp1][nyp1]...

Also I'm not that beginner as I did hello world examples before and I see that this error is different from errors I faced.

Thanks and waiting for help

Johnnydarten

Edited 4 Years Ago by johnnydarten: n/a

>> Actually the size of array needs to be computed at runtime.

Then you should use the "new" command and create the memory dynamically at runtime. You qualified the line as that it "might be" that line. That's the exact line? What's the precise error message? Print out the array sizes right before that line. See if they ever change. If they DON'T change, then no, you CAN declare them prior to run-time, although if they're a pain to work out, it would still be easier to use the "new" command. I still think possibly that the compiler perhaps optimized and TURNED them into constants, thus they were in fact computed at compile time. I can't guarantee that.

If it's crashing at that line, two possibilities at least occur to me...

  1. The compiler tried to guess how big the array need to be at compile time and guessed wrong.
  2. The compiler knew ahead of time or "guessed right", maybe the numbers are too big and it simply can't handle that size array on the stack. In that case, you need to use the heap and the new command.

The bottom line is that if the array dimensions cannot be turned into constants, even if it compiles, you're asking for trouble if you try to allocate a static array with variable dimensions. Looking through the code, a whole bunch of these "variables" are clearly actually constants, so they should be declared as such. Your array dimensions, if they are based on constants, can be constants themselves. For some of them it would be a little tricky. You have an "if" statement based on the number of objects, which should really be a constant. Some clever changing around of constants to #define objects or something similar might be able to turn into constants. Might be more trouble than its worth. But the moral of the story is that if you CANNOT turn those array dimension variables into constants, don't declare them statically even if the compiler lets you. You need to use the "new" command and then set up some pointers in order to use the [] to dereference the array.

Even if you do use "new", for good programming style, you should change anything that doesn't change into a constant.


Here's a tutorial on "new". I don't know if you have experience with pointers and dynamic memory.

http://www.cplusplus.com/doc/tutorial/dynamic/

I will need some time to see if no other problems existed as the original code is much longer (I couldn't post it) so I will respond shortly if the problem repeats when more memory is needed otherwise I will mark the thread as solved. Thanks Vernondozier

This question has already been answered. Start a new discussion instead.