C++ : Strange occurance of SIGSEGV 11

Carlis

Senior member
May 19, 2006
237
0
76
I am trying to debug a piece of code, but the more I try to isolate the error, the more confused I get. The program bellow produces SIGSEGV 11, but if I rewrite the method at the bottom to;

void Iteration::Initiate(){
using namespace std;
cout << beta ;
}

i.e., skip the space in the output, then it works. There is no sanity in this. If it is of any use, I am using xcode 3.0 on osx 10.5 ppc. Also note, that since I have removed some pieces of the program before posting it here, some methods are prototyped, but the behavior of the whole program is no different...

//----------------
#include <iostream>
#include <fstream>
#include <string>
#include <string.h>
#include <stdio.h>
#include <math.h>

class Session
{
public:
void Go();
};

class Iteration
{
public:
Iteration(double ibeta, double isigma, double iepsilon, double ikappa, int ino, double iquanta);
void Iteration::Initiate();
void run(int sweeps);
void write(char *target);
double eval(int x, int y);
double subeval(int x, int y);
double totalEnergy();

static const int Nmax=500;
double kappa, beta, sigma, epsilon; //<n>/<p>=sqrt(20)
double RF[Nmax][Nmax];
double IF[Nmax][Nmax];

double RG[Nmax][Nmax];
double IG[Nmax][Nmax];

double AX[Nmax][Nmax];
double AY[Nmax][Nmax];

int N;

double Xmesh[Nmax][Nmax];
double Ymesh[Nmax][Nmax];
double n;
};



int main(int argc, char* argv[])
{
using namespace std;

Session S1;
S1.Go();

return 0;
}
void Session::Go(){

using namespace std;
using std::ifstream;
using std::cerr;
using std::cout;
using std::endl;
int No=200;
double Beta=0.5; double Sigma=0; double Epsilon=sqrt(20); double Kappa=3; double Quanta=1;

//interpolate(fin, gin, ain, meshin, Xmesh, Nin, Fin, Gin, Ain, N);

Iteration sim=Iteration(Beta, Sigma, Epsilon, Kappa, No, Quanta);
sim.Initiate();
//sim.run(10);
//sim.write("file1.txt");
cout << " Completed ";
}


Iteration::Iteration(double ibeta, double isigma, double iepsilon, double ikappa, int ino, double iquanta){
// initiate mesh...
using namespace std;
beta=ibeta; kappa=ikappa; sigma=isigma; epsilon=iepsilon; n=iquanta;
N=ino;
}

void Iteration::Initiate(){
using namespace std;
cout << beta <<" ";
}
 

MGMorden

Diamond Member
Jul 4, 2000
3,348
0
76
Ok, after playing with it it looks like (for me - I'm on GCC under Linux) I was getting Seg Faults due to trying to call methods on NULL objects.

Instead of:

Session S1;
S1.Go();

Do:

Session *S1;
S1 = new Session();
S1->Go();

And instead of:

Iteration sim=Iteration(Beta, Sigma, Epsilon, Kappa, No, Quanta);
sim.Initiate();

Do:

Iteration *sim;
sim = new Iteration(Beta, Sigma, Epsilon, Kappa, No, Quanta);
sim->Initiate();
 

Ken g6

Programming Moderator, Elite Member
Moderator
Dec 11, 1999
16,284
3,905
75
Declaring Iteration as a function variable could be the killer in gcc. I'm not sure, but that may have led to 500*500*8 doubles == 2 million doubles on the stack. See also this thread.

However, it doesn't sound like that was the problem in Xcode. Xcode also uses gcc, so this is confusing. MGMorden, what version of gcc did you use?
 

sao123

Lifer
May 27, 2002
12,648
201
106
Originally posted by: Carlis
I am trying to debug a piece of code, but the more I try to isolate the error, the more confused I get. The program bellow produces SIGSEGV 11, but if I rewrite the method at the bottom to;

void Iteration::Initiate(){
using namespace std;
cout << beta ;
}

i.e., skip the space in the output, then it works. There is no sanity in this. If it is of any use, I am using xcode 3.0 on osx 10.5 ppc. Also note, that since I have removed some pieces of the program before posting it here, some methods are prototyped, but the behavior of the whole program is no different...

//----------------
#include <iostream>
#include <fstream>
#include <string>
#include <string.h>
#include <stdio.h>
#include <math.h>

class Session
{
public:
void Go();
};

class Iteration
{
public:
Iteration(double ibeta, double isigma, double iepsilon, double ikappa, int ino, double iquanta);
void Iteration::Initiate();
void run(int sweeps);
void write(char *target);
double eval(int x, int y);
double subeval(int x, int y);
double totalEnergy();

static const int Nmax=500;
double kappa, beta, sigma, epsilon; //<n>/<p>=sqrt(20)
double RF[Nmax][Nmax];
double IF[Nmax][Nmax];

double RG[Nmax][Nmax];
double IG[Nmax][Nmax];

double AX[Nmax][Nmax];
double AY[Nmax][Nmax];

int N;

double Xmesh[Nmax][Nmax];
double Ymesh[Nmax][Nmax];
double n;
};



int main(int argc, char* argv[])
{
using namespace std;

Session S1;
S1.Go();

return 0;
}
void Session::Go(){

using namespace std;
using std::ifstream;
using std::cerr;
using std::cout;
using std::endl;
int No=200;
double Beta=0.5; double Sigma=0; double Epsilon=sqrt(20); double Kappa=3; double Quanta=1;

//interpolate(fin, gin, ain, meshin, Xmesh, Nin, Fin, Gin, Ain, N);

Iteration sim=Iteration(Beta, Sigma, Epsilon, Kappa, No, Quanta);
sim.Initiate();
//sim.run(10);
//sim.write("file1.txt");
cout << " Completed ";
}


Iteration::Iteration(double ibeta, double isigma, double iepsilon, double ikappa, int ino, double iquanta){
// initiate mesh...
using namespace std;
beta=ibeta; kappa=ikappa; sigma=isigma; epsilon=iepsilon; n=iquanta;
N=ino;
}

void Iteration::Initiate(){
using namespace std;
cout << beta <<" ";
}


There is something wrong with the bolded line.
1 either sim is a pointer, and you are missing a * or &... OR
2 sim is a variable and you need to overload the = to be able to piecewise copy objects of type iteration.
im guessing since you continued to use a . instead of -> that #2 is the case.
 

Cerebus451

Golden Member
Nov 30, 2000
1,425
0
76
Originally posted by: Ken g6
Declaring Iteration as a function variable could be the killer in gcc. I'm not sure, but that may have led to 500*500*8 doubles == 2 million doubles on the stack. See also this thread.

However, it doesn't sound like that was the problem in Xcode. Xcode also uses gcc, so this is confusing. MGMorden, what version of gcc did you use?
I am fairly certain it is a stack issue. That is almost 16MB of stack space being eaten up by the 1 object. From what I have read, the default stack on MacOSX is only 8MB, but if this process is running with a 16MB stack, it could be that the extra parameter to the cout call is what is finally pushing the process past the stack limit.

Doing what MGMorden suggested and making sim a pointer and doing a new will put that 15.25MB of doubles into the heap instead of on the stack. You could also redesign the class to make the arrays pointers, allocate the memory you need in the constructor, then provide a destructor to free it back up.

NOTE: I haven't tested with gcc since the only copy I have available right now isn't installed properly and the source won't compiled. I tested with xlC on an AIX machine, and when I limit the stack to 16MB, core dump. With an unlimited stack it runs through fine.
 

MGMorden

Diamond Member
Jul 4, 2000
3,348
0
76
Originally posted by: Ken g6
MGMorden, what version of gcc did you use?

I was testing with gcc 3.4.6 on Gentoo Linux.

The stack issue does make perfect sense though. I didn't even think to look at the number of variables being declared in that object, just that as I stepped through it it bombed out right when that constructor was called. Tried starting with the pointer first instead and it started working for me.


 

sao123

Lifer
May 27, 2002
12,648
201
106
the problem isnt necessarily the stack. the problem does occur at the constructor because you cannot do this:
Iteration sim=Iteration(Beta, Sigma, Epsilon, Kappa, No, Quanta);

the equal sign does not KNOW how to do the copy, especially with all the fancy arrays inside, unless you overload the assignemnt operator.


the following code for class iteration should do the trick.

public:
const Iteration &operator=(const Iteration &);

const Iteration &Iteration:perator=(const Iteration &Right_Side)
{
if (&Right_Side != this)
{
kappa = Right_Side.kappa;
beta = Right_Side.beta;
sigma = Right_Side.sigma;
epsilon = Right_Side.epsilon;
N = Right_Side.N;
n = Right_Side.n;

for(int k=0; k<Nmax; k++)
{
for(int j=0; j<Nmax; j++)
{
RF[k][j] = Right_Side.RF[k][j];
IF[k][j] = Right_Side.IF[k][j];
RG[k][j] = Right_Side.RG[k][j];
IG[k][j] = Right_Side.IG[k][j];
AX[k][j] = Right_Side.AX[k][j];
AY[k][j] = Right_Side.AY[k][j];
Xmesh[k][j] = Right_Side.Xmesh[k][j];
Ymesh[k][j] = Right_Side.Ymesh[k][j];
}
}
}
return *this;}
 

iCyborg

Golden Member
Aug 8, 2008
1,327
52
91
Or maybe he should just call the constructor there, seems like that's what he intended anyway:

Iteration sim(Beta, Sigma, Epsilon, Kappa, No, Quanta);
 

sao123

Lifer
May 27, 2002
12,648
201
106
Originally posted by: iCyborg
Or maybe he should just call the constructor there, seems like that's what he intended anyway:

Iteration sim(Beta, Sigma, Epsilon, Kappa, No, Quanta);

also a viable solution
 

Venix

Golden Member
Aug 22, 2002
1,084
3
81
Originally posted by: sao123
the problem isnt necessarily the stack. the problem does occur at the constructor because you cannot do this:
Iteration sim=Iteration(Beta, Sigma, Epsilon, Kappa, No, Quanta);

the equal sign does not KNOW how to do the copy, especially with all the fancy arrays inside, unless you overload the assignemnt operator.


the following code for class iteration should do the trick.

public:
const Iteration &operator=(const Iteration &);

const Iteration &Iteration:perator=(const Iteration &Right_Side)
{
if (&Right_Side != this)
{
kappa = Right_Side.kappa;
beta = Right_Side.beta;
sigma = Right_Side.sigma;
epsilon = Right_Side.epsilon;
N = Right_Side.N;
n = Right_Side.n;

for(int k=0; k<Nmax; k++)
{
for(int j=0; j<Nmax; j++)
{
RF[k][j] = Right_Side.RF[k][j];
IF[k][j] = Right_Side.IF[k][j];
RG[k][j] = Right_Side.RG[k][j];
IG[k][j] = Right_Side.IG[k][j];
AX[k][j] = Right_Side.AX[k][j];
AY[k][j] = Right_Side.AY[k][j];
Xmesh[k][j] = Right_Side.Xmesh[k][j];
Ymesh[k][j] = Right_Side.Ymesh[k][j];
}
}
}
return *this;}

This is incorrect. The compiler-generated assignment operator will correctly copy statically sized arrays. Deep copy semantics would be required if the arrays were dynamically allocated or contained pointers.

Additionally, the assignment operator would never even be called in this case. "Iteration sim = something" calls a copy constructor, not operator=. If "something" is a temporary Iteration, the compiler will remove the temporary and just directly construct sim.

Defining an assignment operator alone is also usually incorrect. If you need operator=, you almost always also need a copy constructor and a destructor.
 

Carlis

Senior member
May 19, 2006
237
0
76
Hi all.
Thank you so much for helping me out, memory issues did not occur to me at all...
I tried changing the size of the arrays and its seems I can use arrays of approx 350*350. This is probably more than I have cpu power to handle any way but I apparently have to look into memory handling a little more since I need to learn c++.

I assume the fact that the program works for smaller arrays imply that the 'stack' was the issue?

There were some other suggestions regarding the call;

>> Iteration sim=Iteration(Beta, Sigma, Epsilon, Kappa, No, Quanta); <<

My intention is to call the constructor in the Iteration class to create an object called sim. I assumed putting '=' assigns an object to a variable. What did I do different from iCyborg;

Iteration sim(Beta, Sigma, Epsilon, Kappa, No, Quanta);

 

iCyborg

Golden Member
Aug 8, 2008
1,327
52
91
The difference is that you're constructing a temporary object on the right side and then assigning it to the variable sim, although as Venix said, in such a situation it would generally call the copy constructor. However, as Venix had also pointed out, there's a good chance that the compiler will recognize this and simply construct sim directly.

I also think it's an issue with the stack, each array is like 2 MB.
 

Carlis

Senior member
May 19, 2006
237
0
76
If I use float instead of double, then I'll be able to use larger arrays, right?
Also, would the execution speed increase if I used floats instead of doubles?
 

degibson

Golden Member
Mar 21, 2008
1,389
0
0
Originally posted by: Carlis
If I use float instead of double, then I'll be able to use larger arrays, right?
2x bigger, assuming your JVM isn't braindead.

Also, would the execution speed increase if I used floats instead of doubles?
Only if the arrays are huge.

Edit: you -> your
 

sao123

Lifer
May 27, 2002
12,648
201
106
Originally posted by: Venix
Originally posted by: sao123
the problem isnt necessarily the stack. the problem does occur at the constructor because you cannot do this:
Iteration sim=Iteration(Beta, Sigma, Epsilon, Kappa, No, Quanta);

the equal sign does not KNOW how to do the copy, especially with all the fancy arrays inside, unless you overload the assignemnt operator.


the following code for class iteration should do the trick.

public:
const Iteration &operator=(const Iteration &);

const Iteration &Iteration:perator=(const Iteration &Right_Side)
{
if (&Right_Side != this)
{
kappa = Right_Side.kappa;
beta = Right_Side.beta;
sigma = Right_Side.sigma;
epsilon = Right_Side.epsilon;
N = Right_Side.N;
n = Right_Side.n;

for(int k=0; k<Nmax; k++)
{
for(int j=0; j<Nmax; j++)
{
RF[k][j] = Right_Side.RF[k][j];
IF[k][j] = Right_Side.IF[k][j];
RG[k][j] = Right_Side.RG[k][j];
IG[k][j] = Right_Side.IG[k][j];
AX[k][j] = Right_Side.AX[k][j];
AY[k][j] = Right_Side.AY[k][j];
Xmesh[k][j] = Right_Side.Xmesh[k][j];
Ymesh[k][j] = Right_Side.Ymesh[k][j];
}
}
}
return *this;}

This is incorrect. The compiler-generated assignment operator will correctly copy statically sized arrays. Deep copy semantics would be required if the arrays were dynamically allocated or contained pointers.

Additionally, the assignment operator would never even be called in this case. "Iteration sim = something" calls a copy constructor, not operator=. If "something" is a temporary Iteration, the compiler will remove the temporary and just directly construct sim.

Defining an assignment operator alone is also usually incorrect. If you need operator=, you almost always also need a copy constructor and a destructor.

to assume this is global for all compilers is naieve... Visual studio 6 makes no such attempt at defining a copy constructor for user defined types. .net compilers may ,but i havent used the newer ones yet.
 
sale-70-410-exam    | Exam-200-125-pdf    | we-sale-70-410-exam    | hot-sale-70-410-exam    | Latest-exam-700-603-Dumps    | Dumps-98-363-exams-date    | Certs-200-125-date    | Dumps-300-075-exams-date    | hot-sale-book-C8010-726-book    | Hot-Sale-200-310-Exam    | Exam-Description-200-310-dumps?    | hot-sale-book-200-125-book    | Latest-Updated-300-209-Exam    | Dumps-210-260-exams-date    | Download-200-125-Exam-PDF    | Exam-Description-300-101-dumps    | Certs-300-101-date    | Hot-Sale-300-075-Exam    | Latest-exam-200-125-Dumps    | Exam-Description-200-125-dumps    | Latest-Updated-300-075-Exam    | hot-sale-book-210-260-book    | Dumps-200-901-exams-date    | Certs-200-901-date    | Latest-exam-1Z0-062-Dumps    | Hot-Sale-1Z0-062-Exam    | Certs-CSSLP-date    | 100%-Pass-70-383-Exams    | Latest-JN0-360-real-exam-questions    | 100%-Pass-4A0-100-Real-Exam-Questions    | Dumps-300-135-exams-date    | Passed-200-105-Tech-Exams    | Latest-Updated-200-310-Exam    | Download-300-070-Exam-PDF    | Hot-Sale-JN0-360-Exam    | 100%-Pass-JN0-360-Exams    | 100%-Pass-JN0-360-Real-Exam-Questions    | Dumps-JN0-360-exams-date    | Exam-Description-1Z0-876-dumps    | Latest-exam-1Z0-876-Dumps    | Dumps-HPE0-Y53-exams-date    | 2017-Latest-HPE0-Y53-Exam    | 100%-Pass-HPE0-Y53-Real-Exam-Questions    | Pass-4A0-100-Exam    | Latest-4A0-100-Questions    | Dumps-98-365-exams-date    | 2017-Latest-98-365-Exam    | 100%-Pass-VCS-254-Exams    | 2017-Latest-VCS-273-Exam    | Dumps-200-355-exams-date    | 2017-Latest-300-320-Exam    | Pass-300-101-Exam    | 100%-Pass-300-115-Exams    |
http://www.portvapes.co.uk/    | http://www.portvapes.co.uk/    |