like to know why it is segmentation fault on simple throw-exception program

E

eric

Dear comp.lang.c++ reader or advced c++ programers:

I copied a piece of code from page 397 of book (Practical C++
programming), example22-1, stack_e1.cpp
about Throwing an Exception.
after a little modification, it successfully compile on my gnu/g++/
ubuntuLinux system
but when i run it, it response
Segmentation fault
-------------------------------------------this is the
program--------------------------------------------------------------
/**************************************************
* stack *
* A file implementing a simple stack class *
**************************************************/
#include <cstdlib>
// #include <string>
#include <iostream>
#include <assert.h>

const int STACK_SIZE = 100; // Maximum size of a stack

/*****************************************************
* bound_err -- a class used to handle out of bounds *
* execeptions. *
*****************************************************/
class bound_err {
public:
const std::string what; // What caused the error

// Initialize the bound error with a message
bound_err(const std::string& i_what) : what(i_what) {};
// Assignment operator defaults
// bound_err(bound_err) -- default copy constructor
// ~ bound_err -- default destructor
};

/*******************************************************
* Stack class *
* *
* Member functions *
* init -- initialize the stack. *
* push -- put an item on the stack. *
* pop -- remove an item from the stack *
*******************************************************/
// The stack itself
class stack {
private:
int count; // Number of items in teh stack
int data[STACK_SIZE]; // The items themselves
public:
// Initialize the stack
stack(): count(0) {};
// Copy constructor defaults
// Assignment operator defaults

// Push an item on teh stack
void push(const int item) throw(bound_err);

// Pop an item from the stack
int pop() throw(bound_err);
};
/
**********************************************************************
* stack::push -- push an item on the stack
*
*
*
* Parameters
*
* item -- item to put in the stack
*

**********************************************************************/
inline void stack::push(const int item) throw(bound_err)
{
if ((count < 0) &&
(count >= sizeof(data)/sizeof(data[0]))) {
throw("Push overflows stack");
}
data[count] = item;
++count;
}
/*********************************************************************
* stack::pop -- get an item off the stack. *
* *
* Returns *
* The top item fromt the stack. *

*********************************************************************/
inline int stack::pop() throw(bound_err)
{
// Stack goes down by one
--count;

if ((count < 0) &&
(count >= sizeof(data)/sizeof(data[0]))) {
throw("Pop underflows stack");
}
// Then we return the top value
return (data[count]);
}
static stack test_stack; // Define a stack for our bounds
checking
/
***************************************************************************
* push_a_lot -- Push too much on to the
stack *

***************************************************************************/
static void push_a_lot() {
int i; // Push counter

for (i=0; i < 5000; i++) {
test_stack.push(i);
}
}

int main()
{
try {
push_a_lot();
}
catch (bound_err& err) {
std::cerr << "Error: Bounds exceeded\n";
std::cerr << "Reason: " << err.what << '\n';
exit (8);
}
catch (...) {
std::cerr << "Error: Unexpected exception occurred\n";
exit(8);
}
return (0);
}
 
I

Ian Collins

Dear comp.lang.c++ reader or advced c++ programers:

I copied a piece of code from page 397 of book (Practical C++
programming), example22-1, stack_e1.cpp
about Throwing an Exception.
after a little modification, it successfully compile on my gnu/g++/
ubuntuLinux system
but when i run it, it response
Segmentation fault

Without digging too deep, this will get you in a whole heap of trouble:

const int STACK_SIZE = 100; // Maximum size of a stack

...

int data[STACK_SIZE]; // The items themselves
...

for (i=0; i < 5000; i++) {
test_stack.push(i);

How big is data? How many items do you push?

<code snipped>

Also using exception specifiers is generally regarded as bad practice.
It will land you in all sorts of problems if something you call throws
some other exception type.
 
V

Victor Bazarov

Dear comp.lang.c++ reader or advced c++ programers:

I copied a piece of code from page 397 of book (Practical C++
programming), example22-1, stack_e1.cpp
about Throwing an Exception.
after a little modification, it successfully compile on my gnu/g++/
ubuntuLinux system
but when i run it, it response
Segmentation fault

Without digging too deep, this will get you in a whole heap of trouble:

const int STACK_SIZE = 100; // Maximum size of a stack

..

int data[STACK_SIZE]; // The items themselves
..

for (i=0; i < 5000; i++) {
test_stack.push(i);

How big is data? How many items do you push?

The whole point of the exercise was to catch the "exceptional" situation
in which _too much_ is pushed. I am guessing you *did* need to dig a
bit deeper (using your words). See the original post again and try
paying attention this time. :*)
<code snipped>

Also using exception specifiers is generally regarded as bad practice.
Really?

It will land you in all sorts of problems if something you call throws
some other exception type.

That can be too deep for the OP. The inquiry looked very much like a
homework (done by the OP, which is commendable), part of a C++ course,
in which they *might* learn later that an exception specification is
frowned upon by some c.l.c++ inhabitants.

V
 
I

Ian Collins

Dear comp.lang.c++ reader or advced c++ programers:

I copied a piece of code from page 397 of book (Practical C++
programming), example22-1, stack_e1.cpp
about Throwing an Exception.
after a little modification, it successfully compile on my gnu/g++/
ubuntuLinux system
but when i run it, it response
Segmentation fault

Without digging too deep, this will get you in a whole heap of trouble:

const int STACK_SIZE = 100; // Maximum size of a stack

..

int data[STACK_SIZE]; // The items themselves
..

for (i=0; i< 5000; i++) {
test_stack.push(i);

How big is data? How many items do you push?

The whole point of the exercise was to catch the "exceptional" situation
in which _too much_ is pushed. I am guessing you *did* need to dig a
bit deeper (using your words). See the original post again and try
paying attention this time. :*)

OK, I dug:

inline void stack::push(const int item) throw(bound_err)
{
if ((count < 0) &&
(count >= sizeof(data)/sizeof(data[0]))) {
throw("Push overflows stack");
}
data[count] = item;
++count;
}

Nothing will be thrown since count can't be negative and >= STACK_SIZE!
That can be too deep for the OP. The inquiry looked very much like a
homework (done by the OP, which is commendable), part of a C++ course,
in which they *might* learn later that an exception specification is
frowned upon by some c.l.c++ inhabitants.

There are some who don't frown upon them?
 
V

Victor Bazarov

Dear comp.lang.c++ reader or advced c++ programers:

I copied a piece of code from page 397 of book (Practical C++
programming), example22-1, stack_e1.cpp
about Throwing an Exception.
after a little modification, it successfully compile on my gnu/g++/
ubuntuLinux system
but when i run it, it response
Segmentation fault
-------------------------------------------this is the
program--------------------------------------------------------------
/**************************************************
* stack *
* A file implementing a simple stack class *
**************************************************/
#include<cstdlib>
// #include<string>
#include<iostream>
#include<assert.h>

Why do you need 'assert.h'?
const int STACK_SIZE = 100; // Maximum size of a stack

/*****************************************************
* bound_err -- a class used to handle out of bounds *
* execeptions. *
*****************************************************/
class bound_err {
public:
const std::string what; // What caused the error

// Initialize the bound error with a message
bound_err(const std::string& i_what) : what(i_what) {};

Format nit-pick: drop the trailing semicolon.
// Assignment operator defaults
// bound_err(bound_err) -- default copy constructor
// ~ bound_err -- default destructor
};

/*******************************************************
* Stack class *
* *
* Member functions *
* init -- initialize the stack. *
* push -- put an item on the stack. *
* pop -- remove an item from the stack *
*******************************************************/
// The stack itself
class stack {
private:
int count; // Number of items in teh stack
int data[STACK_SIZE]; // The items themselves
public:
// Initialize the stack
stack(): count(0) {};

Format nit-pick: drop the trailing semicolon.
// Copy constructor defaults
// Assignment operator defaults

// Push an item on teh stack
void push(const int item) throw(bound_err);

// Pop an item from the stack
int pop() throw(bound_err);
};
/
**********************************************************************
* stack::push -- push an item on the stack
*
*
*
* Parameters
*
* item -- item to put in the stack
*

**********************************************************************/
inline void stack::push(const int item) throw(bound_err)
{
if ((count< 0)&&
(count>= sizeof(data)/sizeof(data[0]))) {

Check the condition. Can 'count' be less than 0 AND greater than the
size of the array *simultaneously*?
throw("Push overflows stack");

Are you sure this throw will actually throw a 'bound_err' as your
specification promises? Put a breakpoint in the c-tor for 'bound_err'
and see whether it gets hit. I suspect that the compiler may not be
able to understand two user conversions in a row (char[] -> string,
string -> bound_err) and throws a pointer to char.
}
data[count] = item;
++count;
}
/*********************************************************************
* stack::pop -- get an item off the stack. *
* *
* Returns *
* The top item fromt the stack. *

*********************************************************************/
inline int stack::pop() throw(bound_err)
{
// Stack goes down by one
--count;

if ((count< 0)&&
(count>= sizeof(data)/sizeof(data[0]))) {

Check the condition. Can 'count' be less than 0 AND greater than the
size of the array *simultaneously*?
throw("Pop underflows stack");

Same note as before, but also, how can 'count' be greater than the size
of the 'data' array here?
}
// Then we return the top value
return (data[count]);
}
static stack test_stack; // Define a stack for our bounds
checking
/
***************************************************************************
* push_a_lot -- Push too much on to the
stack *

***************************************************************************/
static void push_a_lot() {
int i; // Push counter

for (i=0; i< 5000; i++) {

Get used to the C++ idiom of declaring/defining the loop counter inside
the parentheses:

for (int i = 0; i < 5000; i)) ) {
test_stack.push(i);
}
}

int main()
{
try {
push_a_lot();
}
catch (bound_err& err) {
std::cerr<< "Error: Bounds exceeded\n";
std::cerr<< "Reason: "<< err.what<< '\n';
exit (8);
}
catch (...) {
std::cerr<< "Error: Unexpected exception occurred\n";
exit(8);
}
return (0);
}

V
 
V

Victor Bazarov

On 06/ 2/11 10:01 AM, eric wrote:
Dear comp.lang.c++ reader or advced c++ programers:
[...]
Also using exception specifiers is generally regarded as bad practice.
Really?

It will land you in all sorts of problems if something you call throws
some other exception type.

That can be too deep for the OP. The inquiry looked very much like a
homework (done by the OP, which is commendable), part of a C++ course,
in which they *might* learn later that an exception specification is
frowned upon by some c.l.c++ inhabitants.

There are some who don't frown upon them?

<shrug> I don't see them in production code (except the 'throw' with the
empty parens, which promises that nothing is thrown, as I understand
it), so I don't care one way or the other.

V
 
E

eric

On 6/1/2011 6:16 PM, Ian Collins wrote:
On 06/ 2/11 10:01 AM, eric wrote:
Dear comp.lang.c++ reader or advced c++ programers:
 [...]
Also using exception specifiers is generally regarded as bad practice..
Really?
It will land you in all sorts of problems if something you call throws
some other exception type.
That can be too deep for the OP. The inquiry looked very much like a
homework (done by the OP, which is commendable), part of a C++ course,
in which they *might* learn later that an exception specification is
frowned upon by some c.l.c++ inhabitants.
There are some who don't frown upon them?

<shrug> I don't see them in production code (except the 'throw' with the
empty parens, which promises that nothing is thrown, as I understand
it), so I don't care one way or the other.

V

---------------------------------------------------------------
Dear Victor or advanced c++ program(especially on g++ camp):
I follow many of your suggestion, ie change && to || in push
then
after it run
-------------
terminate called after throwing an instance of 'char const*'
Aborted
----------this is better than Segmentation fault, but still not
expected-------

the trouble is happen at call of throw and catch (receiveing) part
it show somehting before throw, but it did not reponse any (or first)
statement in catch block
plz help,(its on gnu/gcc/g++ of linux), thanks a lot in advance, Eric
 
I

Ian Collins

It looks like you still throw a char* pointer instead of bound_err, against
Victor's suggestions. Calling terminate() is expected behavior to me in
this case (and also demonstrates why (non-empty) exception specifications
are bad).

It's also the usual result of using exception specifiers and throwing
something else!
 
V

Victor Bazarov

It looks like you still throw a char* pointer instead of bound_err, against
Victor's suggestions. Calling terminate() is expected behavior to me in
this case (and also demonstrates why (non-empty) exception specifications
are bad).

IOW, try changing your

throw ("blah");
to
throw bound_err("blah");

or change your 'catch' code to catch a pointer to const char *and* drop
the exception specification. Your function does not throw what it is
declared to throw.

V
 
R

red floyd

On 06/ 2/11 10:01 AM, eric wrote:
Dear comp.lang.c++ reader or advced c++ programers:
I copied a piece of code from page 397 of book (Practical C++
programming), example22-1, stack_e1.cpp
about Throwing an Exception.
after a little modification, it successfully compile on my gnu/g++/
ubuntuLinux system
but when i run it, it response
Segmentation fault
Without digging too deep, this will get you in a whole heap of trouble:
const int STACK_SIZE = 100; // Maximum size of a stack
..
int data[STACK_SIZE]; // The items themselves
..
for (i=0; i<  5000; i++) {
test_stack.push(i);
How big is data? How many items do you push?
The whole point of the exercise was to catch the "exceptional" situation
in which _too much_ is pushed.  I am guessing you *did* need to dig a
bit deeper (using your words).  See the original post again and try
paying attention this time. :*)

OK, I dug:

inline void stack::push(const int item) throw(bound_err)
{
     if ((count < 0) &&
            (count >= sizeof(data)/sizeof(data[0]))) {
        throw("Push overflows stack");
     }
     data[count] = item;
     ++count;

}

Nothing will be thrown since count can't be negative and >= STACK_SIZE!

And even if it did, wouldn't it call unexpected(), since it throws a
char const*
instead of a bound_err?
 

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,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top