473,396 Members | 1,871 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Abnormal program termination

I am facing that error message with no idea WHY the reason ? "Abnormal
program termination"

E:\programs\c_lang\iti01\tc201\ch06\ownarr01o01
Enter a number : 25
More numbers (y/n)? y
Enter a number : 30
More numbers (y/n)? n
25.000000
30.000000
The average is 27.500000
Abnormal program termination

E:\programs\c_lang\iti01\tc201\ch06\own>type arr01o01.c

/*#include <stdio.h>
/*-exercise 6.1.1 - calculate average of a series of numbers*/
main ()
{
float number[100];
int no_numbers,i;
float ave(),average;
input_nos(&no_numbers,number);
average=ave(no_numbers,number);
print_nos(number,no_numbers,average);
}

input_nos(count,nos)
int *count;
float *nos;
{
char another_no;
*count=0;
do
{
++(*count);
printf("Enter a number : ");
scanf("%f",&nos[*count]);
if (*count<100)
{
printf("More numbers (y/n)? ");
scanf("\n");
scanf("%c",&another_no);
}
}
while (another_no=='y'&&(*count)<100);
}
float ave(n_n,n)
int n_n;
float *n;
{
float total=0;
int i;
for (i=0;i<=n_n;i++)
total=total+n[i];
return(total/n_n);
}
print_nos(nu,n_n,a)
int n_n;
float *nu,a;
{
int i;
for (i=1;i<=n_n;i++)
printf ("%f\n",nu[i]);
printf ("\n The average is %f \n",a);
}

Sep 1 '06 #1
9 6848
eh**********@gmail.com wrote:
I am facing that error message with no idea WHY the reason ? "Abnormal
program termination"

E:\programs\c_lang\iti01\tc201\ch06\ownarr01o01
Enter a number : 25
More numbers (y/n)? y
Enter a number : 30
More numbers (y/n)? n
25.000000
30.000000
The average is 27.500000
Abnormal program termination

E:\programs\c_lang\iti01\tc201\ch06\own>type arr01o01.c

/*#include <stdio.h>
/*-exercise 6.1.1 - calculate average of a series of numbers*/
main ()
{
float number[100];
int no_numbers,i;
float ave(),average;
input_nos(&no_numbers,number);
average=ave(no_numbers,number);
print_nos(number,no_numbers,average);
}

input_nos(count,nos)
int *count;
float *nos;
{
char another_no;
*count=0;
do
{
++(*count);
printf("Enter a number : ");
scanf("%f",&nos[*count]);
if (*count<100)
{
printf("More numbers (y/n)? ");
scanf("\n");
scanf("%c",&another_no);
}
}
while (another_no=='y'&&(*count)<100);
}
float ave(n_n,n)
int n_n;
float *n;
{
float total=0;
int i;
for (i=0;i<=n_n;i++)
total=total+n[i];
return(total/n_n);
}
print_nos(nu,n_n,a)
int n_n;
float *nu,a;
{
int i;
for (i=1;i<=n_n;i++)
printf ("%f\n",nu[i]);
printf ("\n The average is %f \n",a);
}
The first problem is that the "count" pointer did NOT receive any
storage to hold the values you are storing

The second problem is that the "nos" pointer did not receive any storage
for storing the numbers you enter.

Then the program crashes.

Use:
int count = 0;

#define MAX_INPUT 100
float nos[MAX_INPUT];

And when reading a number, test that you
do not exceed the MAX_INPUT value
Sep 1 '06 #2
jacob navia said:

<snip>
>
The first problem is that the "count" pointer did NOT receive any
storage to hold the values you are storing
Read the program again, more carefully.
>
The second problem is that the "nos" pointer did not receive any storage
for storing the numbers you enter.
Read the program again, more carefully.

<snip>
And when reading a number, test that you
do not exceed the MAX_INPUT value
Read the program again, more carefully.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 1 '06 #3

eh**********@gmail.com wrote:
I am facing that error message with no idea WHY the reason ? "Abnormal
program termination"

E:\programs\c_lang\iti01\tc201\ch06\ownarr01o01
Enter a number : 25
More numbers (y/n)? y
Enter a number : 30
More numbers (y/n)? n
25.000000
30.000000
The average is 27.500000
Abnormal program termination

E:\programs\c_lang\iti01\tc201\ch06\own>type arr01o01.c

/*#include <stdio.h>
/*-exercise 6.1.1 - calculate average of a series of numbers*/
main ()
{
float number[100];
int no_numbers,i;
float ave(),average;
input_nos(&no_numbers,number);
average=ave(no_numbers,number);
print_nos(number,no_numbers,average);
}
Repeat after me: "main() returns an int, so we must supply an int for
it to return."

What happens if you /don't/ return an int out of main()?
Well, "Abnormal program termination" is one possible answer.

[snip]

HTH
--
Lew Pitcher

Sep 1 '06 #4
eh**********@gmail.com wrote:
/*#include <stdio.h>
Um, that's a problem.
/*-exercise 6.1.1 - calculate average of a series of numbers*/
main ()
int main(void). See Lew's response.
input_nos(count,nos)
int *count;
float *nos;
void input_nos( int *count, float *nos )

Your form is (I believe) legal, but you can see why the above is much
preferred.

--
C. Benson Manica | I *should* know what I'm talking about - if I
cbmanica(at)gmail.com | don't, I need to know. Flames welcome.
Sep 1 '06 #5
eh**********@gmail.com wrote:
I am facing that error message with no idea WHY the reason ? "Abnormal
program termination"
The proximate cause is *probably* that you "fall off the
end" of the main() function without telling it what value to
return. main() returns an `int' value that indicates the
program's "exit status;" what *probably* happened is that by
falling off the end you returned some kind of garbage value
as your program's exit status. When your operating system saw
that the exit status was something weird, it warned you that
the program had terminated abnormally.

See below for the cure and a few other hints.
/*#include <stdio.h>
Don't comment this out; you need it.
/*-exercise 6.1.1 - calculate average of a series of numbers*/
main ()
Better style would be `int main(void)', which says
explicitly that main() takes no arguments and returns an
int value.
{
float number[100];
int no_numbers,i;
float ave(),average;
input_nos(&no_numbers,number);
average=ave(no_numbers,number);
print_nos(number,no_numbers,average);
... and here's where you need to return a value as the
program's exit status. The value zero means "successful
completion," so add `return 0;' here.
}

input_nos(count,nos)
int *count;
float *nos;
This is known as the "old-style" or "K&R" method of
describing a function's arguments. In 1989 a new style
was added to the language, and the new method is a much
better way to do things. The old style is still supported
so as not to invalidate the reams and reams of C code that
were written before 1989, but when you write new code there
is virtually no reason to use the old style. Write

void input_nos(int *count, float *nos)

This says that input_nos is a function of two arguments, just
as the old style did, but it also makes the types of those
arguments "visible" to the rest of the program instead of only
inside the function. This allows the compiler to catch silly
mistakes, like accidentally interchanging the arguments when
you call the function. Also, the `void' at the beginning says
this is a function that returns no value.

The only drawback to this style is that you must (usually)
declare the function before you call it, and that might require
writing one extra line of code. Alternatively, you could just
move the function definition up near the top of the source file
("the Pascal disease"), because the definition will also serve
as a declaration.
{
char another_no;
*count=0;
do
{
++(*count);
printf("Enter a number : ");
On some systems you may have trouble getting your
prompts to display properly; see Question 12.4 in the
comp.lang.c Frequently Asked Questions (FAQ) list at
http://c-faq.com/.
scanf("%f",&nos[*count]);
See Question 12.20 in the FAQ.
if (*count<100)
{
printf("More numbers (y/n)? ");
scanf("\n");
scanf("%c",&another_no);
}
}
while (another_no=='y'&&(*count)<100);
There's an off-by-one error in this loop. Array indices
in C begin with [0], yet this loop starts storing the values
at index [1]. Worse, it would allow a sufficiently patient
typist to try to store a value at index [100], but your 100-
element array stops after index [99]. If the attempt is made,
there is no telling what might happen.
}
float ave(n_n,n)
int n_n;
float *n;
Same comment about "old-style" and "new-style." This
time you would write `float ave(int n_n, float *n)'.
{
float total=0;
int i;
for (i=0;i<=n_n;i++)
Off-by-one error again, but a slightly different one.
This time you include all the indices [0] through [n_n]
in the total, but (because of the earlier error) no value
has been stored in the [0] element. From your program's
output it appears you were lucky and the [0] element just
happened to contain a zero, but you cannot rely on being
lucky every time. Your program might have told you that
the average of 25 and 30 is -42.424242, or might have done
something even stranger.
total=total+n[i];
return(total/n_n);
}
print_nos(nu,n_n,a)
int n_n;
float *nu,a;
Same comment about old-style and new style. This time,
you'd write `void print_nos(float *nu, int n_n, float a)'.
{
int i;
for (i=1;i<=n_n;i++)
This matches the off-by-one error in the input loop,
so when you correct the former you'll need to change this
one as well.
printf ("%f\n",nu[i]);
printf ("\n The average is %f \n",a);
}
--
Eric Sosman
es*****@acm-dot-org.invalid

Sep 1 '06 #6
Eric Sosman <es*****@acm-dot-org.invalidwrote:
input_nos(count,nos)
int *count;
float *nos;
This is known as the "old-style" or "K&R" method of
describing a function's arguments.
With no return type specified, does the return type not default to
int? If that's so, then isn't it UB to fail to return a value from a
function that is declared to return one? Or is there some special
dispensation for old-style declarations?

--
C. Benson Manica | I *should* know what I'm talking about - if I
cbmanica(at)gmail.com | don't, I need to know. Flames welcome.
Sep 1 '06 #7
eh**********@gmail.com said:
I am facing that error message with no idea WHY the reason ? "Abnormal
program termination"
<code snipped>

The first thing I did was to compile your program. Here is the list of
diagnostic messages my compiler issued:

foo.c:2: warning: `/*' within comment
foo.c:4: warning: return-type defaults to `int'
foo.c:4: warning: function declaration isn't a prototype
foo.c: In function `main':
foo.c:7: warning: function declaration isn't a prototype
foo.c:7: warning: nested extern declaration of `ave'
foo.c:8: warning: implicit declaration of function `input_nos'
foo.c:10: warning: implicit declaration of function `print_nos'
foo.c:6: warning: unused variable `i'
foo.c:11: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:14: warning: return-type defaults to `int'
foo.c:14: warning: function declaration isn't a prototype
foo.c: In function `input_nos':
foo.c:22: warning: implicit declaration of function `printf'
foo.c:23: warning: implicit declaration of function `scanf'
foo.c:32: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:36: warning: function declaration isn't a prototype
foo.c:48: warning: return-type defaults to `int'
foo.c:48: warning: function declaration isn't a prototype
foo.c: In function `print_nos':
foo.c:55: warning: control reaches end of non-void function

I fixed the first problem by removing the /* from the first line - you were
"commenting out" the <stdio.hinclusion!

The second problem was fixed easily enough, by changing

main ()

to

int main(void)

Your version is legal under C90 rules, but int main(void) is more explicit
about the return type and parameter list.

I fixed these two lines:

foo.c:7: warning: function declaration isn't a prototype
foo.c:7: warning: nested extern declaration of `ave'

by replacing:

float ave(), average;

with

float average;

and placing

float ave(int, float *);

above the main function. Again, your version is actually legal, but the
version given here is more explicit about its types.

Your input_nos() and print_nos() functions had no prototypes, so I added
some:

int input_nos(int *, float *);
int print_nos(float *, int, float);

I changed

int no_numbers,i;

to

int no_numbers;

I added

return 0;

as the last line of main. I changed your (correct, but ancient) K&R-style
function declarator from:

input_nos(count,nos)
int *count;
float *nos;

to the more modern "prototype" style:

int input_nos(int *count, float *nos)

Since input_nos is defined as returning int (which was implicit until I made
it explicit), it needs to return a value, so I added:

return 0;

at its end. Similarly, I changed:

float ave(n_n,n)
int n_n;
float *n;

to:

float ave(int n_n, float *n)

and:

print_nos(nu,n_n,a)
int n_n;
float *nu,a;

to:

int print_nos(float *nu, int n_n, float a)

and added:

return 0;

to its end.

Having made all these modifications, I got a clean compile. I then ran the
code through an indenting tool. Here is the result:

#include <stdio.h>

/*-exercise 6.1.1 - calculate average of a series of numbers*/

float ave(int,
float *);
int input_nos(int *,
float *);
int print_nos(float *,
int,
float);

int main(void)
{
float number[100];
int no_numbers;
float average;

input_nos(&no_numbers, number);
average = ave(no_numbers, number);
print_nos(number, no_numbers, average);
return 0;
}

int input_nos(int *count,
float *nos)
{
char another_no;

*count = 0;
do
{

/* REFER TO EXPLANATION AND CORRECTION, LATER IN ARTICLE */

++(*count);
printf("Enter a number : ");
scanf("%f", &nos[*count]);
if(*count < 100)
{
printf("More numbers (y/n)? ");
scanf("\n");
scanf("%c", &another_no);
}
}
while(another_no == 'y' && (*count) < 100);
return 0;
}
float ave(int n_n,
float *n)
{
float total = 0;
int i;

/* REFER TO EXPLANATION AND CORRECTION, LATER IN ARTICLE */

for(i = 0; i <= n_n; i++)
total = total + n[i];
return (total / n_n);
}
int print_nos(float *nu,
int n_n,
float a)
{
int i;

/* REFER TO EXPLANATION AND CORRECTION, LATER IN ARTICLE */

for(i = 1; i <= n_n; i++)
printf("%f\n", nu[i]);
printf("\n The average is %f \n", a);
return 0;
}

The next step was to attempt to fix your problem! Running the code and using
your test data, I didn't get "Abnormal program termination", but I did get
- the wrong answer! I entered 25 and 30, just like you did, but got a
result of 28.510899, which is clearly wrong. So I had something to debug.
Good.

The first thing to check is that you're using the array properly. At this
point in the discussion, it actually makes sense to take one of Mr Navia's
suggestions seriously [1], and introduce a symbolic constant for the number
of elements in the array:

#define MAX_INPUT 100

We then change the definition of number to:

float number[MAX_INPUT];

and
if(*count < 100)

becomes

if(*count < MAX_INPUT)

Finally:

while(another_no == 'y' && (*count) < 100);

becomes:

while(another_no == 'y' && (*count) < MAX_INPUT);

Let's remember that array elements are counted from 0. That is, number[0] is
the first element. If our array has 100 elements, then, the valid indices
are 0 through 99.

So we want our first write to be to element 0, yes?

In input_nos(), we find this code:

*count = 0;

Index is 0.

do
{
++(*count);

Index is now 1.

printf("Enter a number : ");
scanf("%f", &nos[*count]);

First write goes into element 1! That isn't what we want, so let's fix it:

*count = 0;
do
{
printf("Enter a number : ");
scanf("%f", &nos[*count]);
++(*count);

This time, when we run the program, we get:

me@here./foo
Enter a number : 25
More numbers (y/n)? y
Enter a number : 30
More numbers (y/n)? n
30.000000
2.021596

The average is 28.510798

which is clearly still wrong, so let's continue our analysis by looking at
the average-calculating function, which accepts the number of valid data
and a pointer to the first element in the data array:

float ave(int n_n,
float *n)
{
float total = 0;
int i;

for(i = 0; i <= n_n; i++)

Wait a minute, though - this counts from 0 to n_n. If we have 1 valid
number, it should sum one valid number, i.e. n[0], but you have it as
summing n[0] and n[1]. If you have two numbers, it should sum two numbers -
n[0] and n[1] - but you have it summing three, because you include n[2] as
well. So let's fix that to:

for(i = 0; i < n_n; i++)

....I've changed <= to < so that it sums exactly the right amount of data.
me@here./foo
Enter a number : 25
More numbers (y/n)? y
Enter a number : 30
More numbers (y/n)? n
30.000000
2.021596

The average is 27.500000

Now the /result/ is right, which is good, but the displayed data are wrong.
Specifically, the first one displayed is n[1] rather than n[0], and the
second one is just completely out to lunch. That smacks of an off-by-one
error in the display routine. So let's go look for it:

int print_nos(float *nu,
int n_n,
float a)
{
int i;

for(i = 1; i <= n_n; i++)
printf("%f\n", nu[i]);

And there we have it. This loop needs to be changed to:

for(i = 0; i < n_n; i++)
printf("%f\n", nu[i]);

This final modification gives us the correct answer. To give you some
confidence that this is the case, I averaged four numbers:

me@here./foo
Enter a number : 1
More numbers (y/n)? y
Enter a number : 3
More numbers (y/n)? y
Enter a number : 7
More numbers (y/n)? y
Enter a number : 29
More numbers (y/n)? n
1.000000
3.000000
7.000000
29.000000

The average is 10.000000
Unfortunately, we're not done yet. Observe:

me@here./foo
Enter a number : TEN
More numbers (y/n)? 2.021797

The average is 2.021797

Clearly that's unacceptable. We need to be able to handle this problem, so
let's introduce a fix:

scanf("%f", &nos[*count]);

becomes:

if(scanf("%f", &nos[*count]) != 1)
{
puts("Invalid data. Quitting.");
exit(EXIT_FAILURE);
}

which necessitates the following additional line at the top of the program:

#include <stdlib.h>

Now, when we try to mess the program about, we get this:

Enter a number : TEN
Invalid data. Quitting.

and the program terminates.

I hope you find the above helpful.

[1] Gosh!

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 1 '06 #8


Christopher Benson-Manica wrote On 09/01/06 10:01,:
Eric Sosman <es*****@acm-dot-org.invalidwrote:

>>>input_nos(count,nos)
int *count;
float *nos;

> This is known as the "old-style" or "K&R" method of
describing a function's arguments.


With no return type specified, does the return type not default to
int? If that's so, then isn't it UB to fail to return a value from a
function that is declared to return one? Or is there some special
dispensation for old-style declarations?
It's U.B. only if the caller attempts to use the
value that wasn't returned.

int falloff(void) { /* no return */ }
...
falloff(); /* no U.B. */
x = falloff(); /* U.B. */

One exception: In C99, falling off the end of main()
returns a zero, or behaves as if it did. (I can't be
bothered to look up whether that's only for the initial
call, or also applies to recursive calls.) Apparently
the O.P. was not using a C99 compiler -- his code has
other evidences of non-C99-ness, too.

--
Er*********@sun.com

Sep 1 '06 #9
In article <1157127242.361221@news1nwk>,
Eric Sosman <Er*********@sun.comwrote:
>

Christopher Benson-Manica wrote On 09/01/06 10:01,:
>With no return type specified, does the return type not default to
int? If that's so, then isn't it UB to fail to return a value from a
function that is declared to return one?
It's U.B. only if the caller attempts to use the
value that wasn't returned.
>One exception: In C99, falling off the end of main()
returns a zero, or behaves as if it did.
In C89, a return from the initial call to main() without
specifying a termination status, results in an undefined termination
status being returned to the host environment.

The C standard does not really define what it means to return any
particular status to the host environment. There are the specific
values to indicate success or failure, but as far as C is concerned,
even if you indicate success the host environment could produce
a coredump or walk a disc array off the raised floor or whatever.
The result is thus undefined in any case ;-) (But it'd probably
take a DS 9000 Mark II to act maliciously if the success status
is returned.)
--
"It is important to remember that when it comes to law, computers
never make copies, only human beings make copies. Computers are given
commands, not permission. Only people can be given permission."
-- Brad Templeton
Sep 1 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: John Pote | last post by:
Running my programme in Python 2.3.4 I received the following msg in the consol :- (Pent III running W2K prof) """ Exception in Tkinter callback Traceback (most recent call last): File...
1
by: R6_2003 | last post by:
Hello all, i dunno if that's the right newsgroup to ask, but i'll try, please ignore me if u feel its not 0:) i've been messing with a control panel app for so long.. previously i was using...
3
by: Mahmood Ahmad | last post by:
Hello, I have written a program that reads three types of records, validates them acording to certain requirements and writes the valid records into a binary file. The invalid records are...
2
by: Hugh | last post by:
Hello, Apologies if this has already been answered in here and I can't find it, but can anyone help with this problem? I hope the example code and comments state clearly enough what is...
0
by: Alexander F?hrmann | last post by:
Grüß euch! Wir haben hier in der Firma ein Problem mit Access! Sobald man im Access den VBA-Editor aufrufen will, kommt folgender fehler! -------------------- Runtime Error!
16
by: PyDenis | last post by:
Today, I found strange error while using py2exe: 1. I wrote simple program and save as 1.py: import win32ui import win32con win32ui.MessageBox('Test messageBox.' , 'Test', win32con.MB_OK |...
7
by: Huck Phin | last post by:
OK, so I have looked and looked for something similar to my problem, and I cannot find one. I am writing a program for a HugeInteger, and I am attempting to overload the preincrement,...
6
by: helpswat4 | last post by:
I was wondering if someone could help me with this problem...i get a runtime error everytime i try to play Swat 4 on my PC.It says abnormal program termination and i have no idea why....could someone...
6
by: k3xji | last post by:
Hi all, Is there anyway to detect abnormal interpreter shutdown like (closing from task manager, power shutdown of the PC..etc)? Regards,
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.