I am using Dev C++ Version 4.9.9.2 with Windows Vista Home Premium. I have a program that I has compiled and ran on a Linux machine, however, I am having trouble getting it to work on this machine. I am using one program to call a sub-routines to read in text files. I am fairly certain that the coding is correct, however, if I try to use the debug feature I get a "Segmentation Fault" just after the program enters Main() if I run the debugger to the cursor. I have already tried to add the file suggested for Windows Vita problems (mingw32\3.4.2) but I could not figure out how to add the (c:\dev-cpp\bin\ ) to the programs tab. I have successfully compiled and ran a simple "Hello World" file so maybe it has something to do with how I have my program set up. Hopefully, someone can help with this. My compile log is below.
Compiler: Default compiler
Building Makefile: "C:\C++\Makefile.win"
Executing make...
make.exe -f "C:\C++\Makefile.win" all
g++.exe -DDEBUG hw1.o parse.o -o "HW1.exe" -L"C:/Bloodshed_Dev-Cpp/lib" -g3
Execution terminated
Compilation successful
Thanks,
Chris Link
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks for the help!! Using static variables solved the problem. Now I have a new problem on another program so I may post a new message if I can't figure out my problem.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
If the seg-fault is reported for your program, then it is your program. If it is reported for Dev-C++ or GDB that it is the installation.
To be honest you did well to get the debugger to run at all. It has not worked for me for a long time. Then again it is so atrociously bad I've never worried about fixing it.
>> I could not figure out how to add the (c:\dev-cpp\bin\ )
Tools->Compiler->Programs, then prefix each tool executable listed with c:\dev-cpp\bin\ (for example chanhe make.exe to c:\dev-cpp\bin\make.exe
Clifford
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have now fixed the (c:\dev-cpp\bin\ ) but the problem continues. Maybe I need to be more specific with what happens when I try to run the program. A Windows Error box will pop up saying "HW1.exe has stopped working". I am almost certain there are no problems with my coding considering it compiled and ran fine without any errors. The segmentation fault only occurs when I use the debug feature so I am not sure if it is reporting for Dev-C++ or GDB. Below is my updated compile log. Thanks for the help so far!!
Compiler: Default compiler
Building Makefile: "C:\C++\Makefile.win"
Executing make...
c:\Bloodshed_dev-cpp\bin\make.exe -f "C:\C++\Makefile.win" all
c:\Bloodshed_dev-cpp\bin\g++.exe -DDEBUG hw1.o parse.o -o "HW1.exe" -L"C:/Bloodshed_Dev-Cpp/lib" -g3
Execution terminated
Compilation successful
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
>> I have now fixed the (c:\dev-cpp\bin\ ) but the problem continues.
I did not expect it to fix the problem. It was always a separate issue; you merely chose to mention it in the same post.
Now you are asking us to take your word for it that your code is correct, but it is generating a seg-fault. Occam's razor says that it is your code at fault. Posting a sucessful compile log is not going to help much.
Now if you try to run the following code:
int main(){}
and it still faults, I would suggest that it is indeed not a problem with the code, but anything more complex and you would have to post the code.
It is not unreasonable for a seg fault to occur under debug but not when run stand-alone - the memory environment will be entirely different. An invalid access or uninitialised pointer may just happen to access a real memory address in one run-time environment and not another.
Note also that in C++ the constructors of any static objects are called before entry to main(). If you are running this code in teh debugger, it should stop at the exact point the seg-fault occurs. You may need to unwind the call stack to get back to the point in your code. Unfortunately this is where Dev-C++'s GDB integration shows its uselessness, you will have to resort to the GDB command line. Alternatively use the MinGW Insight debugger.
Clifford
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I will post my code first and see where that gets us. You will have to excuse me because I am still learning about C++ so I do not understand everything you have asked. One other important note is that I used the GNU C++ compiler on my Linux machine when the program worked if that may play any role in the source of the problem. The code is rather lengthy. I have a sub-program that I am also using called Parse.cpp which is basically used to read in characters/numbers (i.e. fparse reads in int values; cparse reads in characters). Thanks again!!!
include <cstdio>
include <cmath>
include <cstring>
include <cstdlib>
include <iostream>
include <fstream>
define PI 3.14159265359
using namespace std;
extern double fparse(char ,int,int); //external function used located in parse.cpp
extern char cparse(char *,int,int); //external function used located in parse.cpp
/**************/
/******start of main*****/
/***************/
int main ()
{
/****variables used for HURDAT data*******/
int i,j,k,tcnt,scnt; // Generic integer variables used for loop indices
double f1,f2,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19,f20; //Generic floating variables used for reading input file
char me[4];
char m0[4];
char f0[50];
char f3[5];
char line[500];
char HR[4];
char TS[4];
/****arrays used to store HURDAT data******/
double month[500][50];
double date[500][50];
int lcnt[50];
int this_lcnt;
double lat[500][4][50];
double lon[500][4][50];
double wind[500][4][50];
double press[500][4][50];
/*****variables used for Rawindsonde data*******/
int m,n,p,q,r,s;
/*****arrays used for Rawindsonde data******/
char id[100][4];
char sname[100][20];
double sid[100];
float g0[100];
float g1[100];
/****variables used for comparison**********/
double dx;
double dy;
double dlon;
double dlat;
double nlat;
double dist;
/****************/
/*****Beginning of code********/
/***************/
FILE infile1; //declares infile1 as an input/read file
FILE infile2; //declares infile2 as an input/read file
FILE infile3; //declares infile3 as an input/read file
FILE outfile1; //declares outfile1 as an output file
FILE *outfile2; //declares outfile2 as an output file
infile1 = fopen("2004-Landfall_HURDAT.txt", "r"); //opens HURDAT file for input
if(infile1 == NULL) //validates infile opens the HURDAT file
{
printf("Cannot open HURDAT file.\n");
return 1;
}
else //if file opens then it will read in data
{
scnt = 1; //used to set first storm to 1
fgets(line,500,infile1);
while (!feof(infile1)) //stays in loop until end of file
{
sprintf (me,"M=");
sprintf (HR,"HR");
sprintf (TS,"TS");
strcpy(m0,cparse(line,17,2)); //read storm name
strcpy(f3,cparse(line,6,2)); //read month and stores char value
if ((strncmp(m0,me,2) == 0))
{
strcpy(f0,cparse(line,35,10)); //read storm name
printf(f0); //output storm name
f1 = fparse(line,12,4); //read year
printf("- %4.0lf\n",f1); //output year
lcnt[scnt] = 0; //used to set position in array (days)
}
else if ((strncmp(f3,HR,2) != 0) && (strncmp(f3,TS,2) != 0)) //exits loop when HR or TS are present
{
f2 = fparse(line,6,2); //read month and stores int value
f20 = fparse(line,9,2); //read day of month
f4 = fparse(line,12,3); //read 0z lat
f4 = f4/10.0;
f5 = fparse(line,16,3); //read 0z lon
f5 = f5*-1/10.0;
f6 = fparse(line,20,3); //read 0z wind
f7 = fparse(line,24,4); //read 0z pressure
f8 = fparse(line,29,3); //read 6z lat
f8 = f8/10.0;
f9 = fparse(line,33,3); //read 6z lon
f9 = f9*-1/10.0;
f10 = fparse(line,37,3); //read 6z wind
f11 = fparse(line,41,4); //read 6z pressure
f12 = fparse(line,46,3); //read 12z lat
f12 = f12/10.0;
f13 = fparse(line,50,3); //read 12z lon
f13 = f13*-1/10.0;
f14 = fparse(line,54,3); //read 12z wind
f15 = fparse(line,58,4); //read 12z pressure
f16 = fparse(line,63,3); //read 18z lat
f16 = f16/10.0;
f17 = fparse(line,67,3); //read 18z lon
f17 = f17*-1/10.0;
f18 = fparse(line,71,3); //read 18z wind
f19 = fparse(line,75,4); //read 18z pressure
infile2 = fopen("U.S. Rawindsonde Sites.txt", "r"); //opens Rawindsonde file for input
if(infile2 == NULL) //validates infile opens the Rawindsonde file
{
cout << "Cannot open Rawindsonde file.\n";
return 1;
}
else //if file opens then it will read in data
{
fgets(line,500,infile2);
while (!feof(infile2)) //stays in loop until end of file
{
for (m=0; m<80; m++)
{
strcpy(id[m],cparse(line,0,3)); //read 3 letter code
sid[m] = fparse(line,5,5); //read station ID
g0[m] = fparse(line,48,6); //read Lat
g1[m] = fparse(line,55,7); //read lon
fgets(line,500,infile2);
}
}
}
fclose (infile2);
printf("Completed Rawindsonde\n");
/*****************/
/****Compare Lat/Lon of Rawindsonde/HURDAT*********/
/*****************/
Your main function has around 4Mb of local variables, the normal stack size for a process thread is around 2Mb - that is the cause of your problem, you have exceeded the processes stack bounds.
You need to learn about C++ storage allocation and memory management. There are three methods of storage allocation in in C++ (and C for that matter); static, dynamic, and automatic. Actually there is a fourth - register, but you can ignore that.
Using static allocation, the required space is determined at compile time, and is permanently allocated for the duration of tge processes execution.
Dynamic allocation is determined at run time, and is allocated fromteh time it is instantiated to the time it is explicitly deleted or freed.
Automatic variables are allocated on the stack and exist from the point of declaration until the end of the {...} block in which they are declared. Every thread in every process gets allocated a stack. Because there may be many threads in many processes, the stack size is necessarily limited.
In your case because since the bulk of your program's variables are declared at the top of the main() function, declaring them static would solve your stack overflow while making little or no difference to your program's footprint (because the lifetime of an auto variable in main() is more or less the same as that of a static variable). However in a more complex program this approach would probably be impractical and wasteful of memory - large amounts of memory might be permanantly allocated while not actually being used. In these situations, dynamic allocation (using the new and delete operators) would be the better approach.
Let this be a lesson; in C and C++, the fact that your code runs does not make it correct.
If you are able to run your code on Linux, you might consider the Valgrind tool on your code to perform memory usage analysis. Unfortunately there is no similar free tool on Windows that I am aware of.
Clifford.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I hope the above makes sense. Reading it back I am cringing at the use of the plural " processes " where I'd intended the possessive " process' ". Typos are just typos, but I'd hate to appear illiterate! ;-)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I am using Dev C++ Version 4.9.9.2 with Windows Vista Home Premium. I have a program that I has compiled and ran on a Linux machine, however, I am having trouble getting it to work on this machine. I am using one program to call a sub-routines to read in text files. I am fairly certain that the coding is correct, however, if I try to use the debug feature I get a "Segmentation Fault" just after the program enters Main() if I run the debugger to the cursor. I have already tried to add the file suggested for Windows Vita problems (mingw32\3.4.2) but I could not figure out how to add the (c:\dev-cpp\bin\ ) to the programs tab. I have successfully compiled and ran a simple "Hello World" file so maybe it has something to do with how I have my program set up. Hopefully, someone can help with this. My compile log is below.
Compiler: Default compiler
Building Makefile: "C:\C++\Makefile.win"
Executing make...
make.exe -f "C:\C++\Makefile.win" all
g++.exe -DDEBUG hw1.o parse.o -o "HW1.exe" -L"C:/Bloodshed_Dev-Cpp/lib" -g3
Execution terminated
Compilation successful
Thanks,
Chris Link
Thanks for the help!! Using static variables solved the problem. Now I have a new problem on another program so I may post a new message if I can't figure out my problem.
If the seg-fault is reported for your program, then it is your program. If it is reported for Dev-C++ or GDB that it is the installation.
To be honest you did well to get the debugger to run at all. It has not worked for me for a long time. Then again it is so atrociously bad I've never worried about fixing it.
>> I could not figure out how to add the (c:\dev-cpp\bin\ )
Tools->Compiler->Programs, then prefix each tool executable listed with c:\dev-cpp\bin\ (for example chanhe make.exe to c:\dev-cpp\bin\make.exe
Clifford
I have now fixed the (c:\dev-cpp\bin\ ) but the problem continues. Maybe I need to be more specific with what happens when I try to run the program. A Windows Error box will pop up saying "HW1.exe has stopped working". I am almost certain there are no problems with my coding considering it compiled and ran fine without any errors. The segmentation fault only occurs when I use the debug feature so I am not sure if it is reporting for Dev-C++ or GDB. Below is my updated compile log. Thanks for the help so far!!
Compiler: Default compiler
Building Makefile: "C:\C++\Makefile.win"
Executing make...
c:\Bloodshed_dev-cpp\bin\make.exe -f "C:\C++\Makefile.win" all
c:\Bloodshed_dev-cpp\bin\g++.exe -DDEBUG hw1.o parse.o -o "HW1.exe" -L"C:/Bloodshed_Dev-Cpp/lib" -g3
Execution terminated
Compilation successful
>> I have now fixed the (c:\dev-cpp\bin\ ) but the problem continues.
I did not expect it to fix the problem. It was always a separate issue; you merely chose to mention it in the same post.
Now you are asking us to take your word for it that your code is correct, but it is generating a seg-fault. Occam's razor says that it is your code at fault. Posting a sucessful compile log is not going to help much.
Now if you try to run the following code:
int main(){}
and it still faults, I would suggest that it is indeed not a problem with the code, but anything more complex and you would have to post the code.
It is not unreasonable for a seg fault to occur under debug but not when run stand-alone - the memory environment will be entirely different. An invalid access or uninitialised pointer may just happen to access a real memory address in one run-time environment and not another.
Note also that in C++ the constructors of any static objects are called before entry to main(). If you are running this code in teh debugger, it should stop at the exact point the seg-fault occurs. You may need to unwind the call stack to get back to the point in your code. Unfortunately this is where Dev-C++'s GDB integration shows its uselessness, you will have to resort to the GDB command line. Alternatively use the MinGW Insight debugger.
Clifford
I will post my code first and see where that gets us. You will have to excuse me because I am still learning about C++ so I do not understand everything you have asked. One other important note is that I used the GNU C++ compiler on my Linux machine when the program worked if that may play any role in the source of the problem. The code is rather lengthy. I have a sub-program that I am also using called Parse.cpp which is basically used to read in characters/numbers (i.e. fparse reads in int values; cparse reads in characters). Thanks again!!!
include <cstdio>
include <cmath>
include <cstring>
include <cstdlib>
include <iostream>
include <fstream>
define PI 3.14159265359
using namespace std;
extern double fparse(char ,int,int); //external function used located in parse.cpp
extern char cparse(char *,int,int); //external function used located in parse.cpp
/**************/
/******start of main*****/
/***************/
int main ()
{
/****variables used for HURDAT data*******/
int i,j,k,tcnt,scnt; // Generic integer variables used for loop indices
double f1,f2,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19,f20; //Generic floating variables used for reading input file
char me[4];
char m0[4];
char f0[50];
char f3[5];
char line[500];
char HR[4];
char TS[4];
/****arrays used to store HURDAT data******/
double month[500][50];
double date[500][50];
int lcnt[50];
int this_lcnt;
double lat[500][4][50];
double lon[500][4][50];
double wind[500][4][50];
double press[500][4][50];
/*****variables used for Rawindsonde data*******/
int m,n,p,q,r,s;
/*****arrays used for Rawindsonde data******/
char id[100][4];
char sname[100][20];
double sid[100];
float g0[100];
float g1[100];
/****variables used for comparison**********/
double dx;
double dy;
double dlon;
double dlat;
double nlat;
double dist;
/****variables used for sounding data*******/
double l0;
int sstart;
int acnt,wcnt;
double s0,s1,s2,s3,s4,s5;
double sdate,stime,smonth,syear;
double dir,spd;
double prsndt[5000];
double zzsndt[5000];
double prsndw[5000];
double zzsndw[5000];
double ttsnd[5000];
double tdsnd[5000];
double wspd[5000];
double wdir[5000];
double uusnd[5000];
double vvsnd[5000];
char inmonth;
char JUN[4];
char JUL[4];
char AUG[4];
char SEP[4];
char OCT[4];
char NOV[4];
char l1[4];
char ssid[4];
char file2[50];
char file1[50];
/****************/
/*****Beginning of code********/
/***************/
FILE infile1; //declares infile1 as an input/read file
FILE infile2; //declares infile2 as an input/read file
FILE infile3; //declares infile3 as an input/read file
FILE outfile1; //declares outfile1 as an output file
FILE *outfile2; //declares outfile2 as an output file
/***************/
/*****HURDAT code*******/
/******************/
for(j=0; j<50; j++)
{
for(i=0; i<4; i++)
{
for(k=0; k<300; k++)
{
lat[k][i][j] = -999.9;
lon[k][i][j] = -999.9;
wind[k][i][j] = -999.9;
press[k][i][j] = -999.9;
}
}
}
printf("press enter to continue..");
cin.get();
infile1 = fopen("2004-Landfall_HURDAT.txt", "r"); //opens HURDAT file for input
if(infile1 == NULL) //validates infile opens the HURDAT file
{
printf("Cannot open HURDAT file.\n");
return 1;
}
else //if file opens then it will read in data
{
scnt = 1; //used to set first storm to 1
fgets(line,500,infile1);
while (!feof(infile1)) //stays in loop until end of file
{
sprintf (me,"M=");
sprintf (HR,"HR");
sprintf (TS,"TS");
strcpy(m0,cparse(line,17,2)); //read storm name
strcpy(f3,cparse(line,6,2)); //read month and stores char value
/*****store fparse values*****/
tcnt = 0; //used to count hours/days
this_lcnt = lcnt[scnt]; //dummy variable for lcnt
month[scnt][this_lcnt] = f2;
date[scnt][this_lcnt] = f20;
lat[scnt][tcnt][this_lcnt] = f4;
lon[scnt][tcnt][this_lcnt] = f5;
wind[scnt][tcnt][this_lcnt] = f6;
press[scnt][tcnt][this_lcnt] = f7;
tcnt++;
lat[scnt][tcnt][this_lcnt] = f8;
lon[scnt][tcnt][this_lcnt] = f9;
wind[scnt][tcnt][this_lcnt] = f10;
press[scnt][tcnt][this_lcnt] = f11;
tcnt++;
lat[scnt][tcnt][this_lcnt] = f12;
lon[scnt][tcnt][this_lcnt] = f13;
wind[scnt][tcnt][this_lcnt] = f14;
press[scnt][tcnt][this_lcnt] = f15;
tcnt++;
lat[scnt][tcnt][this_lcnt] = f16;
lon[scnt][tcnt][this_lcnt] = f17;
wind[scnt][tcnt][this_lcnt] = f18;
press[scnt][tcnt][this_lcnt] = f19;
lcnt[scnt]++;
}
else
scnt++;
}
fclose(infile1);
printf("Completed HURDAT\n");
/*****display HURDAT results*******/
/***************/
/*******Rawindsonde Code*******/
/******************/
for(q=0; q<100; q++)
{
sid[q] = 99999;
g0[q] = -999.9;
g1[q] = -999.9;
}
infile2 = fopen("U.S. Rawindsonde Sites.txt", "r"); //opens Rawindsonde file for input
if(infile2 == NULL) //validates infile opens the Rawindsonde file
{
cout << "Cannot open Rawindsonde file.\n";
return 1;
}
else //if file opens then it will read in data
{
fgets(line,500,infile2);
while (!feof(infile2)) //stays in loop until end of file
{
for (m=0; m<80; m++)
{
strcpy(id[m],cparse(line,0,3)); //read 3 letter code
sid[m] = fparse(line,5,5); //read station ID
g0[m] = fparse(line,48,6); //read Lat
g1[m] = fparse(line,55,7); //read lon
fgets(line,500,infile2);
}
}
}
fclose (infile2);
printf("Completed Rawindsonde\n");
/*****************/
/****Compare Lat/Lon of Rawindsonde/HURDAT*********/
/*****************/
sprintf (file1,"2004_soundings_to_get.txt");
outfile1 = fopen(file1,"w");
for(k=1; k<scnt; k++)
{
for(j=0; j<lcnt[k]; j++)
{
for(i=0; i<4; i++)
{
for (n=0; n<80; n++)
{
dlat = lat[k][i][j] - g0[n];
dlon = lon[k][i][j] - g1[n];
nlat = lat[k][i][j] * (PI/180);
dx = 111 * dlon * cos (nlat);
dy = 111 * dlat;
dist = sqrt((dxdx) + (dydy));
}
fclose (outfile1);
printf("completed comparison of lat/lon for Rawindsonde/Hurdat\n");
/***************/
/******Close File********/
/***************/
printf("press enter to continue..");
cin.get();
return 0;
}
Your main function has around 4Mb of local variables, the normal stack size for a process thread is around 2Mb - that is the cause of your problem, you have exceeded the processes stack bounds.
You need to learn about C++ storage allocation and memory management. There are three methods of storage allocation in in C++ (and C for that matter); static, dynamic, and automatic. Actually there is a fourth - register, but you can ignore that.
Using static allocation, the required space is determined at compile time, and is permanently allocated for the duration of tge processes execution.
Dynamic allocation is determined at run time, and is allocated fromteh time it is instantiated to the time it is explicitly deleted or freed.
Automatic variables are allocated on the stack and exist from the point of declaration until the end of the {...} block in which they are declared. Every thread in every process gets allocated a stack. Because there may be many threads in many processes, the stack size is necessarily limited.
In your case because since the bulk of your program's variables are declared at the top of the main() function, declaring them static would solve your stack overflow while making little or no difference to your program's footprint (because the lifetime of an auto variable in main() is more or less the same as that of a static variable). However in a more complex program this approach would probably be impractical and wasteful of memory - large amounts of memory might be permanantly allocated while not actually being used. In these situations, dynamic allocation (using the new and delete operators) would be the better approach.
Let this be a lesson; in C and C++, the fact that your code runs does not make it correct.
If you are able to run your code on Linux, you might consider the Valgrind tool on your code to perform memory usage analysis. Unfortunately there is no similar free tool on Windows that I am aware of.
Clifford.
... further, I just checked my facts (after the event), and unfortunately Valgrind does not perform stack overflow checks.
I believe that VC++ 2008's debugger will report stack overflows, and the Express Edition is free - recommended.
I hope the above makes sense. Reading it back I am cringing at the use of the plural " processes " where I'd intended the possessive " process' ". Typos are just typos, but I'd hate to appear illiterate! ;-)