Segmentation fault

V

vaib

Hi all,
When I run the following code on gcc it gives me "Segmentation fault".
Can anyone throw some light on what's happening ? It compiles fine. I
used RHEL 5.

#include<stdio.h>
#include<stdlib.h>
int main()
{
int fun(char *);
int x;
char *s;
printf("\nEnter number as string:");
scanf("%s",s);
x = fun(s);
printf("\nThe entered number was %d",x);
exit(EXIT_SUCCESS);
}

int fun(char *s)
{
int i;
i=0;
while((*s)!='\0')
{
i=i*10;
i=i + (*s - '0');
s++;
}
return i;
}

thanking in anticipation.
Vaib
 
L

Lew Pitcher

Le Fri, 20 Feb 2009 10:36:40 -0600,
Obnoxious User a écrit :


To a char ! No ? :-D

No. That is what /sort/ of pointer 's' is, not what it is pointing to.

To make it painfully clear, s is not pointing to anything.
Now, think of what might happen if you tried to store something at the char
that 's' is pointing to. Since 's' isn't pointing to anything, where will
that character go? What might the effects of storing something this way be?

--
Lew Pitcher

Master Codewright & JOAT-in-training | Registered Linux User #112576
http://pitcher.digitalfreehold.ca/ | GPG public key available by request
---------- Slackware - Because I know what I'm doing. ------
 
K

Keith Thompson

vaib said:
When I run the following code on gcc it gives me "Segmentation fault".
Can anyone throw some light on what's happening ? It compiles fine. I
used RHEL 5.
[...]
char *s;
printf("\nEnter number as string:");

What is the value of s here?
scanf("%s",s);

scanf reads characters from stdin and writes them into the array
pointed to by s. You haven't allocated such an array.

If you crank up the warning and optimization levels on your compiler,
it will likely warn you that you're using an uninitialized variable.

Note also that "%s" doesn't limit the number of characters that can be
stored. However big an array you allocate, this scanf call can write
beyond the end of it.

[...]
 
K

Kojak

Le Fri, 20 Feb 2009 12:00:54 -0500,
Lew Pitcher a écrit :
No. That is what /sort/ of pointer 's' is, not what it is pointing to.

To make it painfully clear, s is not pointing to anything.
Now, think of what might happen if you tried to store something at
the char that 's' is pointing to. Since 's' isn't pointing to
anything, where will that character go? What might the effects of
storing something this way be?

ROTFL :-D

A little bit nervous? ;-)

Do you know what's a smiley ? It was just an humoristic reply.

That is, you said, I quote:

"if you tried to store something at
the char that 's' is pointing to"

and juste previously:

"That is what /sort/ of pointer 's' is,
not what it is pointing to."

Funny, isn't it ? ;-)


ROTFLPIMP !

Sorry, :-D
 
J

Jens Thoms Toerring

vaib said:
When I run the following code on gcc it gives me "Segmentation fault".
Can anyone throw some light on what's happening ? It compiles fine. I
used RHEL 5.

That something compiles without any hickups only shows that
the syntax is right, it unfortunately doesn't ensures that
the logic of your program is correct.

I hope you don't mind that I don't just point out the
direct caus of your problem but also point out a few
other things that could be problems beside...
#include<stdio.h>
#include<stdlib.h>
int main()

Since your main() function doesn't take arguments it's
clearer if you write

int main( void );
{
int fun(char *);

While there's nothing wrong about declaring functions
in a functions it's rarely done n most programs I have
seen. But that's your decision.
int x;
char *s;

Here you ask for a pointer to char. That pointer now points
to a random position in memory.
printf("\nEnter number as string:");

There's nothing else than a string the user could enter;-)
A problem here is that the output isn't guaranteed to
appear immediately, so the user may see nothing of it.
To make sure that outout of printf() appears on the
users screen the string either has to end in '\n' or
you have to enforce it by calling

fflush( stdout );
scanf("%s",s);

Here things go badly wrong. 's' is just a pointer, pointing
to some unknown place. You can be lucky in that it points
to a position in memory you don't have permission to write
to because in that case you may get a segementation fault,
telling you that something is badly wrong immediately. But
you also could be less lucky and 's' points to memory that
you can write to but are not allowed to, and in that case
it might look as if everything is fine while in reality you
just overwrote some data important for your program, but
that only get used at some later time. That could result
in the program crashing later or in computing some results
that are wrong.

So, having just a pointer doesn't mean that you also
have memory it is pointing to it. The pointer must be
initialized to point to memory that's yours. One way
to make sure that's the case is to define an array of
chars and pass that to scanf() like

char s[ 100 ];

or to allocate memory and make 's' point to that, like
in

s = malloc( 100 * sizeof *c )
if ( s == NULL ) {
fprintf( stderr, "Sorry, not enough memory\n" );
exit( EXIT_FAiLURE );
}

Note that you always should check if malloc() did give
you the memory you asked for and react accordingly!
(The 'sizeof *s' is a bit redundant since. as long as
's' is a pointer to char, it's 1 by definition, putting
it in or not in this case is a question of taste.)

But when you do that then there's another problem due
to the use of scanf(). Let's assume that you have memory
that can hold 100 chars. That looks like long enough
for an integer in string form. But the user who enters
the number can do stupid things, he could enter a lot
more characters, and then you still would write over
memory that's not your's, again with possibly catas-
trophic consequences. So, using scanf() to try to
get input from the user is inherently unsafe in thed
form you have used it. You can get around that by
specifying the maximum number of characters you're
prepared to read, e.g.

char s[ 100 ];

scanf( "%99s", s );

or also

scanf( "%99[0-9]", s );

if you want to make sure that reading stops when a non-
digit character gets found in the input. Note the '99'
instead of 100 - that's necessary since scanf() still
needs to but a '\0' character at the end of the string.

If you use scanf() it's also prudent to check its return
value which allows you to check how many items it got.
If the user e.g. hits Ctrl-D (or Ctrl-Z if he's using
Windows) instead of entering a stitrng, then scanf()
wouldn't be able to read anything and 's' would remain
unchanged (and since the 's' array isn't initialized
you would go on converting random chars from it).

An alternative to scanf() is fgets(). You have to tell
fgets() how many chars it's supposed to read at maximum
and you then can take the returned string apart in your
program.
x = fun(s);
printf("\nThe entered number was %d",x);

Again, keep in mind that strings not ending in '\n' may
get stuck in the internal buffers of printf() until some
later time (or until you call fflush()). Here it's not a
real problem since ending the program will flush these
buffers, but in a real program that might be different.
exit(EXIT_SUCCESS);

While calling exit() does the job of ending the program
why not simply return?
int fun(char *s)
{
int i;
i=0;

That can be done in a single line

int i = 0;
while((*s)!='\0')

You don't need paranthesis around '*s', the '*' operator
"binds" rather strongly.
{
i=i*10;
i=i + (*s - '0');
s++;
}
return i;
}

I hope you realize that, if the user entered anything else
than digits, this function will give you strange results.
In a real program you also would probably use e.g. strtol()
instead of writing your own version...

Regards, Jens
 
V

vaib

Wow ! thank you so much all of you . That was some really nice
discussion for me. Yes i am learning C. I got the concept there.As one
of the guys pointed out I also wanted to ask the difference between
declaring a function inside main (or any other function) and declaring
it outside of anything.

thank you again.
 
C

CBFalconer

vaib said:
When I run the following code on gcc it gives me "Segmentation
fault". Can anyone throw some light on what's happening ? It
compiles fine. I used RHEL 5.

#include<stdio.h>
#include<stdlib.h>
int main() {
int fun(char *);
int x;
char *s;
printf("\nEnter number as string:");
scanf("%s",s);
x = fun(s);
printf("\nThe entered number was %d",x);
exit(EXIT_SUCCESS);
}

int fun(char *s) {
int i;
i=0;
while ((*s)!='\0') {
i=i*10;
i=i + (*s - '0');
s++;
}
return i;
}

[1] c:\c\junk>cc junk.c
junk.c: In function `main':
junk.c:6: warning: `s' might be used uninitialized in this function

What is RHEL 5 and what has it got to do with this?
 
K

Keith Thompson

CBFalconer said:
vaib said:
When I run the following code on gcc it gives me "Segmentation
fault". Can anyone throw some light on what's happening ? It
compiles fine. I used RHEL 5.
[snip]
[1] c:\c\junk>cc junk.c
junk.c: In function `main':
junk.c:6: warning: `s' might be used uninitialized in this function

What is RHEL 5 and what has it got to do with this?

Red Hat Enterprise Linux version 5, and not much, respectively.

Specifying the system he's using doesn't hurt, and could help us to
help him to find a more appropriate place to ask if it turns out that
it matters.

Incidentally, you seem to be approximately the fifth person to point
out that s is uninitialized. The first post to mention this was
posted about 9 hours before yours. And yes, that post did arrive on
your server; you and I use the same one.
 
C

CBFalconer

Keith said:
.... snip ...

Incidentally, you seem to be approximately the fifth person to
point out that s is uninitialized. The first post to mention
this was posted about 9 hours before yours. And yes, that post
did arrive on your server; you and I use the same one.

However my reader shows posts in order of date/time, so the first
thing I read is the original question. I reply, and then find
other answers.
 
K

Keith Thompson

CBFalconer said:
However my reader shows posts in order of date/time, so the first
thing I read is the original question. I reply, and then find
other answers.

And that is why you waste time and space answering questions that have
already been answered. My advice is to change your habits; read the
other responses in the thread before posting your own.
 
I

Ian Collins

CBFalconer said:
Keith Thompson wrote:
.... snip ...

However my reader shows posts in order of date/time, so the first
thing I read is the original question. I reply, and then find
other answers.

Why don't you read threads as threads?
 
K

Kaz Kylheku

However my reader

By the above term, Chucky is, of course, referring to that
software which identifies itself as:

X-Mailer: Mozilla 4.75 [en] (Win98; U)

The software authors themselves do not agree that it is a reader.
They didn't dare using the ``X-Newsreader'' header for this.

Chucky has been on Usenet for a good decade now, if not more,
yet still hasn't figured out what software to install.
shows posts in order of date/time, so the first

That is, unlike an /actual/ Usenet news reader, which displays some kind
of tree of all hitherto visible articles that are identified as being
in the same discussion thread by their References: headers.

Such a display makes it obvious that a given root article has had
nine hours worth of replies already.
thing I read is the original question. I reply, and then find
other answers.

Good order, Chucky! Emily Postnews is beaming with pride regarding
one of her best pupils.
 
G

Guest

Since your main() function doesn't take arguments it's
clearer if you write

int main( void );


While there's nothing wrong about declaring functions
in a functions it's rarely done n most programs I have
seen. But that's your decision.

so instead of writing your code like this:

#include <stdio.h>
#include <stdlib.h>

int main (void)
{
int fun (char *);
...
}

int fun (char *s)
{
...
}

you could write:

#include <stdio.h>
#include <stdlib.h>

int fun (char *);

int main (void)
{
...
}

int fun (char *s)
{
...
}

which makes the declaration available to the whole program.
Or, my preference, rearrange your program so it doesn't need
a separate declaration


#include <stdio.h>
#include <stdlib.h>

int fun (char *s)
{
...
}

int main (void)
{
...
}


<snip>
 
J

James Kuyper

CBFalconer said:
Keith Thompson wrote:
... snip ...

However my reader shows posts in order of date/time, so the first
thing I read is the original question. I reply, and then find
other answers.

Yes, and that is precisely what he is complaining about. You shouldn't
waste other people's time by posting responses that duplicate things
someone else has already pointed out. In addition to wasting our time,
it also make you look as though you're too stupid to use your newsreader
properly. I seriously considered replacing "you look as though" with "it
clear that". However, I think this has more to do with stubborn
selfishness than with stupidity.

According to your message headers, you're using Mozilla, which is quite
capable of letting you read other people's responses to a given message
before sending your own. It isn't even necessary to read all the
messages in the newsgroup - Mozilla is quite capable of displaying a
thread as a tree, so you can easily read all of the responses to one
message before reading any other messages on that same thread.
 
C

CBFalconer

.... snip ...

Or, my preference, rearrange your program so it doesn't need
a separate declaration

#include <stdio.h>
#include <stdlib.h>

int fun (char *s) {
...
}

int main (void) {
...
}

Which has the added advantage of eliminating silly errors in
copying the function declaration to the prototype.
 
C

CBFalconer

Ian said:
Why don't you read threads as threads?

I do. But within threads, things are organized as query followed
by answer. If there are multiple answers they are sorted by time.
e.g.:

.query t
|--.ans_1 t+1
|--.ans_2 t+22
| |--.ans_2_2 t+33
| |--.ans_2_3 t+34
|--.ans_3 t+3

etc. So I will see ans_1 and ans_2_* before ans_3.
 
K

Keith Thompson

CBFalconer said:
I do. But within threads, things are organized as query followed
by answer. If there are multiple answers they are sorted by time.
e.g.:

.query t
|--.ans_1 t+1
|--.ans_2 t+22
| |--.ans_2_2 t+33
| |--.ans_2_3 t+34
|--.ans_3 t+3

etc. So I will see ans_1 and ans_2_* before ans_3.

Does that mean you have to respond to "query" before reading "ans_1"?
If it does, either get a better newsreader or learn to use the one you
have.

In mine, for example, I see a list of articles similar to the one you
describe. When I read an article, it's marked as read, but it doesn't
vanish from the list. That means I can easily read an entire thread
(at least the subset of it that's currently available), then go back
to an article I've already read and post a followup to it if there's a
point nobody else has made yet.

My newsreader is Gnus, which runs under emacs; if you don't like
emacs, you're not going to like Gnus. But any decent newsreader
should let you do something similar.
 
R

Richard

CBFalconer said:
I do. But within threads, things are organized as query followed
by answer. If there are multiple answers they are sorted by time.
e.g.:

.query t
|--.ans_1 t+1
|--.ans_2 t+22
| |--.ans_2_2 t+33
| |--.ans_2_3 t+34
|--.ans_3 t+3

etc. So I will see ans_1 and ans_2_* before ans_3.

Which begs the question : then why do you insist on posting garbage to
threads which have already been well answered?
 

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,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top