Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > like to know why it is segmentation fault on simple throw-exception program

Reply
Thread Tools

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

 
 
eric
Guest
Posts: n/a
 
      06-01-2011
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:ush -- push an item on the stack
*
*
*
* Parameters
*
* item -- item to put in the stack
*

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

************************************************** *******************/
inline int stack:op() 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 (;
}
catch (...) {
std::cerr << "Error: Unexpected exception occurred\n";
exit(;
}
return (0);
}

 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      06-01-2011
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?

<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.

--
Ian Collins
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      06-01-2011
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:
>>
>> 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 do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      06-01-2011
On 06/ 2/11 10:34 AM, Victor Bazarov wrote:
> 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:
>>>
>>> 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:ush(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!

>> 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?

--
Ian Collins
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      06-01-2011
On 6/1/2011 6:01 PM, 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
> -------------------------------------------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:ush -- push an item on the stack
> *
> *
> *
> * Parameters
> *
> * item -- item to put in the stack
> *
>
> ************************************************** ********************/
> inline void stack:ush(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:op -- get an item off the stack. *
> * *
> * Returns *
> * The top item fromt the stack. *
>
> ************************************************** *******************/
> inline int stack:op() 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 (;
> }
> catch (...) {
> std::cerr<< "Error: Unexpected exception occurred\n";
> exit(;
> }
> return (0);
> }
>


V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      06-01-2011
On 6/1/2011 6:44 PM, Ian Collins wrote:
> On 06/ 2/11 10:34 AM, Victor Bazarov wrote:
>> 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
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
eric
Guest
Posts: n/a
 
      06-02-2011
On Jun 1, 3:46*pm, Victor Bazarov <(E-Mail Removed)> wrote:
> On 6/1/2011 6:44 PM, Ian Collins wrote:
>
>
>
> > On 06/ 2/11 10:34 AM, Victor Bazarov wrote:
> >> 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
> --
> I do not respond to top-posted replies, please don't ask


---------------------------------------------------------------
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
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      06-02-2011
On 06/ 2/11 05:28 PM, Paavo Helde wrote:
> eric<(E-Mail Removed)> wrote in
> news:(E-Mail Removed):
>
>> 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-------

>
> 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!

--
Ian Collins
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      06-02-2011
On 6/2/2011 1:28 AM, Paavo Helde wrote:
> eric<(E-Mail Removed)> wrote in
> news:(E-Mail Removed):
>
>> 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-------

>
> 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
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
red floyd
Guest
Posts: n/a
 
      06-02-2011
On Jun 1, 3:44*pm, Ian Collins <(E-Mail Removed)> wrote:
> On 06/ 2/11 10:34 AM, Victor Bazarov wrote:
>
>
>
>
>
>
>
>
>
> > 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:

>
> >>> 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:ush(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?

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Segmentation fault in interpreter doing simple MySQL Jon Rosen Ruby 1 07-16-2010 09:59 AM
Simple XOR encryption code issues (segmentation fault) John Williams C++ 11 03-13-2007 01:52 PM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
Re: Why segmentation fault in this simple code? Minti C Programming 1 08-09-2004 11:20 PM
Why segmentation fault in this simple code? Polar C Programming 11 08-09-2004 07:26 PM



Advertisments