The dreaded segfault

P

Prasad

Hi folks,

I am trying to debug the following program. Debugging the core file
revealed segfault at possibleFlows[k][m]=0 when values of
states=36, labels=40. It works fine for lesser values.

What could be the reason? Integer overflow or out of memory? Am i
missing something obvious?
I am using ubuntu and GNU g++.

int main()
{
const int states=36, labels=40;
int fromLabels=labels, toLabels=labels;
int fromStates=states, toStates=states;
int successors[fromStates][toStates];
int stateMatrix[fromStates][toStates][fromLabels][toLabels];
int possibleFlows[states][fromLabels][toLabels];
//Initialise all possible flows to 0
for(int i=0;i<states;i++)
for(int k=0;k<fromLabels;k++)
for(int m=0; m<toLabels;m++)
possibleFlows[k][m]=0; //Segmentation fault here

//Populate with given values
//S0
possibleFlows[0][1][0]=1;
possibleFlows[0][2][0]=1;
.........................rest of the
code....................................
 
I

Ian Collins

Prasad said:
Hi folks,

I am trying to debug the following program. Debugging the core file
revealed segfault at possibleFlows[k][m]=0 when values of
states=36, labels=40. It works fine for lesser values.

What could be the reason? Integer overflow or out of memory? Am i
missing something obvious?
I am using ubuntu and GNU g++.

int main()
{
const int states=36, labels=40;
int fromLabels=labels, toLabels=labels;
int fromStates=states, toStates=states;
int successors[fromStates][toStates];


This isn't legal C++, are you build this as C?
 
S

Stephen Horne

int possibleFlows[states][fromLabels][toLabels];
//Initialise all possible flows to 0
for(int i=0;i<states;i++)
for(int k=0;k<fromLabels;k++)
for(int m=0; m<toLabels;m++)
possibleFlows[k][m]=0; //Segmentation fault here


My brains hurting so I may be wrong, but you might want to try...

possibleFlows[m][k]=0;

I always mix up my multi-dimensional subscripting, so maybe you have
to.
 
P

Prasad

Prasad said:
Hi folks,
I am trying to debug the following program.  Debugging the core file
revealed segfault at possibleFlows[k][m]=0 when values of
states=36, labels=40. It works fine for lesser values.

What could be the reason? Integer overflow or out of memory? Am i
missing something obvious?
I am using ubuntu and GNU g++.
int main()
{
   const int states=36, labels=40;
   int fromLabels=labels, toLabels=labels;
   int fromStates=states, toStates=states;
   int successors[fromStates][toStates];

This isn't legal C++, are you build this as C?


This is a c++ program. I have removed all the namespace declaration,
headers and other code which was not relevant to the problem.
 
I

Ian Collins

Prasad said:
Prasad said:
Hi folks,
I am trying to debug the following program. Debugging the core file
revealed segfault at possibleFlows[k][m]=0 when values of
states=36, labels=40. It works fine for lesser values.
What could be the reason? Integer overflow or out of memory? Am i
missing something obvious?
I am using ubuntu and GNU g++.
int main()
{
const int states=36, labels=40;
int fromLabels=labels, toLabels=labels;
int fromStates=states, toStates=states;
int successors[fromStates][toStates];

This isn't legal C++, are you build this as C?
Please don't quote signatures.

This is a c++ program. I have removed all the namespace declaration,
headers and other code which was not relevant to the problem.


No it is not, C++ does not have VLAs and successors is a VLA.
 
B

Bernd Strieder

Hello,
I am trying to debug the following program. Debugging the core file
revealed segfault at possibleFlows[k][m]=0 when values of
states=36, labels=40. It works fine for lesser values.

What could be the reason? Integer overflow or out of memory? Am i
missing something obvious?
I am using ubuntu and GNU g++.

int main()
{
const int states=36, labels=40;
int fromLabels=labels, toLabels=labels;
int fromStates=states, toStates=states;
int successors[fromStates][toStates];
int stateMatrix[fromStates][toStates][fromLabels][toLabels];


That is 36*36*40*40*4 bytes or over 8MB for stateMatrix alone, which
might be over the maximum stack size of your platform. Try ulimit -s in
a shell, it tells the max stacksize in kiB. Exceeding stacksize results
in segfaults.

You will have to use dynamic allocation or global variables to solve
that problem portably. Usually overusing stack is not a sign of
professional style in programming.

Bernd Strieder
 
K

Kai-Uwe Bux

Prasad said:
Hi folks,

I am trying to debug the following program. Debugging the core file
revealed segfault at possibleFlows[k][m]=0 when values of
states=36, labels=40. It works fine for lesser values.

What could be the reason? Integer overflow or out of memory? Am i
missing something obvious?
I am using ubuntu and GNU g++.

int main()
{
const int states=36, labels=40;
int fromLabels=labels, toLabels=labels;
int fromStates=states, toStates=states;
int successors[fromStates][toStates];
int stateMatrix[fromStates][toStates][fromLabels][toLabels];


The above tries to allocate 2073600 ints. That could burst limits of what
g++ is willing to do.

Commenting out that line, the code runs with g++ on my computer.
int possibleFlows[states][fromLabels][toLabels];
//Initialise all possible flows to 0
for(int i=0;i<states;i++)
for(int k=0;k<fromLabels;k++)
for(int m=0; m<toLabels;m++)
possibleFlows[k][m]=0; //Segmentation fault here

//Populate with given values
//S0
possibleFlows[0][1][0]=1;
possibleFlows[0][2][0]=1;
........................rest of the
code....................................



Best

Kai-Uwe Bux
 
I

Ian Collins

Kai-Uwe Bux said:
Prasad said:
Hi folks,

I am trying to debug the following program. Debugging the core file
revealed segfault at possibleFlows[k][m]=0 when values of
states=36, labels=40. It works fine for lesser values.

What could be the reason? Integer overflow or out of memory? Am i
missing something obvious?
I am using ubuntu and GNU g++.

int main()
{
const int states=36, labels=40;
int fromLabels=labels, toLabels=labels;
int fromStates=states, toStates=states;
int successors[fromStates][toStates];
int stateMatrix[fromStates][toStates][fromLabels][toLabels];


The above tries to allocate 2073600 ints. That could burst limits of what
g++ is willing to do.

And it ain't C++!
 
K

Kai-Uwe Bux

Ian said:
Kai-Uwe Bux said:
Prasad said:
Hi folks,

I am trying to debug the following program. Debugging the core file
revealed segfault at possibleFlows[k][m]=0 when values of
states=36, labels=40. It works fine for lesser values.

What could be the reason? Integer overflow or out of memory? Am i
missing something obvious?
I am using ubuntu and GNU g++.

int main()
{
const int states=36, labels=40;
int fromLabels=labels, toLabels=labels;
int fromStates=states, toStates=states;
int successors[fromStates][toStates];
int stateMatrix[fromStates][toStates][fromLabels][toLabels];


The above tries to allocate 2073600 ints. That could burst limits of what
g++ is willing to do.

And it ain't C++!


I know. The compiler is required to issue a diagnostic and can then go on a
compile anyway. But we know that the compiler compiles anyway; and that the
code is not C++ is somewhat besides the point of why a segfault happens.


Best

Kai-Uwe Bux
 
P

Prasad

Thanks Bernd. That is indeed the problem. The stack limit is 10 MB. My
bad for not taking it into account.
I will use malloc() to overcome the problem.

Hello,


I am trying to debug the following program.  Debugging the core file
revealed segfault at possibleFlows[k][m]=0 when values of
states=36, labels=40. It works fine for lesser values.

What could be the reason? Integer overflow or out of memory? Am i
missing something obvious?
I am using ubuntu and GNU g++.
int main()
{
const int states=36, labels=40;
int fromLabels=labels, toLabels=labels;
int fromStates=states, toStates=states;
int successors[fromStates][toStates];
int stateMatrix[fromStates][toStates][fromLabels][toLabels];

That is 36*36*40*40*4 bytes or over 8MB for stateMatrix alone, which
might be over the maximum stack size of your platform. Try ulimit -s in
a shell, it tells the max stacksize in kiB. Exceeding stacksize results
in segfaults.

You will have to use dynamic allocation or global variables to solve
that problem portably. Usually overusing stack is not a sign of
professional style in programming.

Bernd Strieder
 
S

Stephen Horne

I know. The compiler is required to issue a diagnostic and can then go on a
compile anyway. But we know that the compiler compiles anyway; and that the
code is not C++ is somewhat besides the point of why a segfault happens.

Probably agreed, but I'm confused. What is going on with that example,
exactly?

I tried compiling - GCC 3.4.5 didn't give me that required diagnostic
even with -Wall. All it told me about was a couple of unused
variables.

The obvious mistake is that fromLabels etc are not marked const. To be
honest, I was surprised that the use of those variables in what should
surely need to be constant expressions compiled at all.

Havn't tried VC++, but I'm pretty confident it will choke.

Adding the two missing const flags doesn't fix the segfault, so
assuming I'm on the right lines, I agree that it's irrelevant to the
problem at hand - especially as this is probably just a
hastily-prepared-simple-example thing.

I'd love to know what's going on, but surely it's just a
compiler-specific extension?

Being over-pedantic myself, I'm confident that compiler-specific
extensions aren't outlawed by the standard, so I don't see how their
use can make something "not C++". Not portable, of course, and
off-topic, but that's not the same thing.

BTW - I've looked in the GCC manual, but for some reason I can't find
the option to turn off all compiler-specific extensions. The dialect
section gives plenty of options, but they all seem to need me to know
which extension I want to turn off. Don't read the manual for me, of
course, but if anyone knows off the top of their head?
 
K

Kai-Uwe Bux

Stephen said:
Probably agreed, but I'm confused. What is going on with that example,
exactly?

An array declaration has the form

D1 [constant-expression_opt];

and the array bound in the example are not constant-expressions.

I tried compiling - GCC 3.4.5 didn't give me that required diagnostic
even with -Wall. All it told me about was a couple of unused
variables.

The obvious mistake is that fromLabels etc are not marked const. To be
honest, I was surprised that the use of those variables in what should
surely need to be constant expressions compiled at all.

Havn't tried VC++, but I'm pretty confident it will choke.

Adding the two missing const flags doesn't fix the segfault, so
assuming I'm on the right lines, I agree that it's irrelevant to the
problem at hand - especially as this is probably just a
hastily-prepared-simple-example thing.

I'd love to know what's going on, but surely it's just a
compiler-specific extension?

Probably. It is a little disconcerting that there seems to be no compiler
switch to turn off the extension. (At least I did not find anything that
rings a bell in the man page.)

Being over-pedantic myself, I'm confident that compiler-specific
extensions aren't outlawed by the standard, so I don't see how their
use can make something "not C++". Not portable, of course, and
off-topic, but that's not the same thing.

Right. [1.4/8] puts forth the requirements for extensions. A diagnostic is
required.


[snip]


Best

Kai-Uwe Bux
 
I

Ian Collins

Stephen said:
Probably agreed, but I'm confused. What is going on with that example,
exactly?
To restore the snipped code:

const int states=36, labels=40;
int fromLabels=labels, toLabels=labels;
int fromStates=states, toStates=states;
int successors[fromStates][toStates];

successors is a variable length array (in C99 terms). C++ does not have
VLAs.
I tried compiling - GCC 3.4.5 didn't give me that required diagnostic
even with -Wall. All it told me about was a couple of unused
variables.
gcc has had its own version of VLAs for a very long time.

gcc 4 will give the required diagnostic if you invoke it in a conforming
mode:

g++ /tmp/x.cc -ansi -pedantic
/tmp/x.cc: In function 'int main()':
/tmp/x.cc:11: error: ISO C++ forbids variable-size array 'successors'
 
S

Stephen Horne

successors is a variable length array (in C99 terms). C++ does not have
VLAs.
Thanks.

g++ /tmp/x.cc -ansi -pedantic

Strange that those options aren't in the "C++ Dialect" section - just
double checked. I still should have found them though. Oh well.

Thanks again.
 
L

Lionel B

On Fri, 17 Oct 2008 07:28:04 +0100, Stephen Horne wrote:

[...]
BTW - I've looked in the GCC manual, but for some reason I can't find
the option to turn off all compiler-specific extensions. The dialect
section gives plenty of options, but they all seem to need me to know
which extension I want to turn off. Don't read the manual for me, of
course, but if anyone knows off the top of their head?

For the current C++ standard (precisely, ISO/IEC 14882:1998 + ISO/IEC
14882:2003) you probably want (at least):

-ansi -pedantic

or equivalently:

-std=c++98 -pedantic

See subsection "2.2 C++ language" of:

http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Standards.html#Standards

Confusingly, the actual options are documented in Section 3.4 "Options
Controlling C Dialect" (since this includes options for both C and C++):

http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/C-Dialect-Options.html

If you use the GNU Standard C++ library (you probably do) then you might
also want to define the macro -D_GLIBCXX_CONCEPT_CHECKS for more
diagnostics. See:

http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt03ch08.html

HTH,
 
J

James Kanze

Stephen Horne wrote:

[...]
gcc 4 will give the required diagnostic if you invoke it in a
conforming mode:
g++ /tmp/x.cc -ansi -pedantic
/tmp/x.cc: In function 'int main()':
/tmp/x.cc:11: error: ISO C++ forbids variable-size array 'successors'

That works, but if I understand correctly, the exact meaning of
-ansi may change in time. A more precise replacement would be
-std=c++98.

In practice, with any compiler, you'll need a lot of options for
everyday use. For g++ under Solaris, for example, I use:

$ echo $GppFlags
-std=c++98 -pedantic -ffor-scope -fno-gnu-keywords -foperator-
names -pipe -Wall -W -Woverloaded-virtual -Wno-sign-compare -Wno-
deprecated -Wno-non-virtual-dtor -Wpointer-arith -Wno-unused -Wno-
switch -Wno-missing-braces -Wno-long-long -static-libgcc -ggdb3 -
D_GLIBCXX_CONCEPT_CHECKS -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
$ echo $GppOFlags
-std=c++98 -pedantic -ffor-scope -fno-gnu-keywords -foperator-
names -pipe -Wall -W -Woverloaded-virtual -Wno-sign-compare -Wno-
deprecated -Wno-non-virtual-dtor -Wpointer-arith -Wno-unused -Wno-
switch -Wno-missing-braces -Wno-long-long -static-libgcc -O3 -fomit-
frame-pointer -finline-functions

I'm not sure that all of them are (still) necessary, and I'm
probably missing a few useful ones because I use the same
environment variable with older versions of g++. (Note too that
at least one of the options, -Wno-long-long, is there to turn on
an extension.)
 
L

Lionel B

Stephen Horne wrote:
[...]
gcc 4 will give the required diagnostic if you invoke it in a
conforming mode:
g++ /tmp/x.cc -ansi -pedantic
/tmp/x.cc: In function 'int main()':
/tmp/x.cc:11: error: ISO C++ forbids variable-size array 'successors'

That works, but if I understand correctly, the exact meaning of -ansi
may change in time. A more precise replacement would be -std=c++98.

My understanding was that "-ansi" will always refer to the current
standard, which at this moment is the one enforced by -std=c++98...
having said which, I've just re-read the relevant section in the latest
docs and it doesn't actually say that. In fact it doesn't say anything
beyond "-ansi is equivalent to -std=c++98". Hmm...
 
J

James Kanze

Stephen Horne wrote:
[...]
gcc 4 will give the required diagnostic if you invoke it in
a conforming mode:
g++ /tmp/x.cc -ansi -pedantic
/tmp/x.cc: In function 'int main()':
/tmp/x.cc:11: error: ISO C++ forbids variable-size array 'successors'
That works, but if I understand correctly, the exact meaning
of -ansi may change in time. A more precise replacement
would be -std=c++98.
My understanding was that "-ansi" will always refer to the
current standard, which at this moment is the one enforced by
-std=c++98... having said which, I've just re-read the
relevant section in the latest docs and it doesn't actually
say that. In fact it doesn't say anything beyond "-ansi is
equivalent to -std=c++98". Hmm...

But of course, that documentation is only valid for 4.3.x. I
would expect that when g++ gets around to supporting C++03,
-ansi would be the equivalent of -std=c++03. If the code you're
compiling was written for C++98, that wouldn't be what you want.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top