segmentation fault

R

ramu

Hi,
int main(void)
{
char ch='a';
printf("%s",ch);
return 0;
}

Why does this give segmentation fault?

Regards,
 
M

Martin Ambuhl

ramu said:
Hi,
int main(void)
{
char ch='a';
printf("%s",ch);
return 0;
}

Why does this give segmentation fault?

Because ch is a char (containing 'a'), not a string.
If you want to print a char, tell printf so:

#include <stdio.h> /* necessary for printf */
int main(void)
{
char ch='a';
printf("%c\n",ch); /* note '%c' and the '\n' */
return 0;
}

If you want to print a string, provide one:

#include <stdio.h> /* necessary for printf */
int main(void)
{
char ch[]="a"; /* a string, equivalent to
char ch[] = {'a', 0};
*/
printf("%s\n",ch); /* note the '\n' */
return 0;
}
 
R

ramu

Hi,
Thanks for you answer.

I want to know exactly how does it give segmentation fault? And can you
explain the significance of ' \n' in the above code?

Regards
 
V

Vladimir S. Oka

ramu said:
Hi,
Thanks for you answer.

Please provide context. How to:

"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: said:
I want to know exactly how does it give segmentation fault?

You'll have to study your compiler/OS to get an answer to this, and that
is off topic here (even if you said what they were).
And can you explain the significance of ' \n' in the above code?

If printf() is not terminated by a '\n' it's not guaranteed to output
anything.
 
M

Martin Ambuhl

ramu said:
Hi,
Thanks for you answer.

I want to know exactly how does it give segmentation fault?

Because the "%s" specifier tells printf that a string will be printed,
and a string is terminated with a 0. But 'a' is a single char with no 0;
printf will search into memory not allocated by your program for that 0,
and that is not allowed.
And can you
explain the significance of ' \n' in the above code?

Without an end-of-line character '\n' at the end of the last output
line, there are no guarantees about what will happen, including whether
you will ever see that line, whether (if it appears) it will have any
prompt on the same or next line or even be overwritten by that prompt.
 
K

Keith Thompson

Martin Ambuhl said:
Because the "%s" specifier tells printf that a string will be printed,
and a string is terminated with a 0. But 'a' is a single char with no
0; printf will search into memory not allocated by your program for
that 0, and that is not allowed.

The code in question was:

char ch='a';
printf("%s",ch);

The fact that the 'a' isn't followed by a '\0' isn't the issue.
Given some plausible assumptions about how parameters are passed,
the value of 'a' (97 on an ASCII-based system) will be interpreted by
printf() as if it were a pointer value. So it *might* print characters
starting at memory address 97 until it happens to run into a '\0'.
Or it might die immediately if that address doesn't exist or is
write-protected.

And that's just assuming that a character (almost certainly promoted
to int) and a char* are passed to printf() in the same location. The
"plausible assumptions" I mentioned above are absolutely *not*
guaranteed by the standard, and there are real-world implementations
where they don't apply. The *only* thing guaranteed is that the code
invokes undefined behavior, defined as "behavior, upon use of a
nonportable or erroneous program construct or of erroneous data, for
which this International Standard imposes no requirements". The
standard joke here is that it can make demons fly out your nose;
that's obviously unrealistic, but an implementation that actually did
that wouldn't violate the standard (just the laws of physics).

If you want to understand why the code behaves in a particular way on
a particular implementation, the C standard is silent on the subject;
you might ask in a newsgroup specific to your compiler or system.
 
K

Kenneth Brody

ramu said:
Hi,
int main(void)
{
char ch='a';
printf("%s",ch);
return 0;
}

Why does this give segmentation fault?

Because you lied to printf(). You told printf() to expect a pointer to
a nul-terminated string, and instead passed a char.

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
M

Mark McIntyre

Hi,
Thanks for you answer.


Please quote enough of the previous message for context. To do so from
Google, click "show options" and use the Reply shown in the expanded
header. For more informatio, please go here
I want to know exactly how does it give segmentation fault?

If you mean "why precisely does my computer decide this is a
segmentation fault", then you'd need to ask in a group specialising in
your OS. As far as C is concerned, its merely a bug.
And can you
explain the significance of ' \n' in the above code?

'\n' means "print a newline".

You should buy a decent C book, it will explain all this stuff. Usenet
is NOT a good place to learn C.
#
 
J

John Bode

ramu said:
Hi,
int main(void)
{
char ch='a';
printf("%s",ch);
return 0;
}

Why does this give segmentation fault?

Regards,

The %s conversion specifier expects its corresponding argument to be
the starting address of a zero-terminated array of char. printf() is
taking the value of 'a' (ASCII 97) and intepreting that as an address.
The problem is that 97 is an invalid address, hence the segfault.

You want to use the %c conversion specifier to print single characters.


int main(void)
{
char ch = 'a';
char str[] = "a"; /* {'a', 0} */

printf ("ch=%c, str=%s\n", ch, str);
return 0;
}
 
W

Walter Roberson

The %s conversion specifier expects its corresponding argument to be
the starting address of a zero-terminated array of char. printf() is
taking the value of 'a' (ASCII 97) and intepreting that as an address.
The problem is that 97 is an invalid address, hence the segfault.

ASCII? What's that? And why is 97 an invalid address?

Sounds like you haven't been programming on the DS2000 lately.
 
J

John Bode

Walter said:
ASCII? What's that?

Some character encoding standard that isn't EBCDIC. Seems to be in
widespread use. Picked as a common but arbitrary example.
And why is 97 an invalid address?

Because it's causing the segfault.
Sounds like you haven't been programming on the DS2000 lately.

Yeah, I haven't had to support multiple platforms for a while now.

;-)
 
J

Jordan Abel

Some character encoding standard that isn't EBCDIC. Seems to be in
widespread use. Picked as a common but arbitrary example.


Because it's causing the segfault.

Wrong - "Because it's not the result of an address-of operator or the
name of an array". Any such value which does happen to be a valid
address is only one in spite of those facts, not because of it. see also
"Undefined Behavior" and "Passing the incorrect type to fprintf". Who
says it's not really the address 0x12340061 that's passed (where '1234'
is garbage)?
 
W

Walter Roberson

John Bode said:
Walter said:
Some character encoding standard that isn't EBCDIC. Seems to be in
widespread use. Picked as a common but arbitrary example.
Because it's causing the segfault.

There is nothing in C that would prevent 'a' from having
the value 0x00B00001 (imagine the upper 16 bits contains the flags,
isupper, isgraphic, isalnum, and the lower 16 bits containing the
relative offset of characters that meet that flag combination).
There is nothing in C that would prevent 0x00B00001 from being a valid
int-aligned address -- int addresses do not -have- to be even
(e.g., sizeof(char) == sizeof(int)). So the real problem could be,
for example, that 'a' happens to correspond to an address in a segment
owned by the user but with an execute-only attribute.

Even if ASCII did happen to be the character set in use, 97 could
be a valid int address, especially on machines that automatically
trap unaligned fetches and transparently rerun them a byte at a time.

So although your answer might have been correct about what happened
on the OP's machine, it isn't -exactly- the right answer in terms of C.
 
E

Emmanuel Delahaye

ramu a écrit :
Hi,
int main(void)
{
char ch='a';
printf("%s",ch);
return 0;
}

Why does this give segmentation fault?

Regards,

Because you are invoking several undefined behaviours.

"%s" expects the address of the first element of an array of initialized
char terminated by a 0.

Additionally, the prototype of printf() is required and is not in scope.

#include <stdio.h>

int main (void)
{
char *ch = "a";
printf("%s\n", ch);
return 0;
}

is fine.
 
E

Emmanuel Delahaye

ramu a écrit :
I want to know exactly how does it give segmentation fault?

There is no general reponse to this question. The program is invoking
several undefined behaviours, meaning that the behaviour is
unpredictable. It's generally a waste of time to try tu understand what
happens exactly. The code is wrong, Just fix it. Period.
And can you
explain the significance of ' \n' in the above code?

This belongs to your textbook. We don't provide level 0 explanations.

If you want a free decent C-book, try this one (it's on line)

http://publications.gbdirect.co.uk/c_book/

(sounds to be down at the moment)
 
K

Keith Thompson

Emmanuel Delahaye said:
ramu a écrit :

There is no general reponse to this question. The program is invoking
several undefined behaviours, meaning that the behaviour is
unpredictable. It's generally a waste of time to try tu understand
what happens exactly. The code is wrong, Just fix it. Period.


This belongs to your textbook. We don't provide level 0 explanations.

I'm going to assume that ramu wasn't asking what '\n' (note: *not*
' \n') means (a new-line character), but was asking about the reason for
it, which is a relatively subtle point.

C99 7.19.2p2 says:

A text stream is an ordered sequence of characters composed into
lines, each line consisting of zero or more characters plus a
terminating new-line character. Whether the last line requires a
terminating new-line character is implementation-defined.

So a program whose output is not terminated by a new-line may not work
correctly (even if it uses fflush(stdout)). As a practical matter,
it's not uncommon for a final partial output line to be printed and
then overwritten by a prompt after the program terminates.

(If ramu actually didn't know that '\n' means new-line, then you're
right, a textbook or tutorial would be a better resource than this
newsgroup.)
 
D

Dave Thompson

The code in question was:

char ch='a';
printf("%s",ch);

The fact that the 'a' isn't followed by a '\0' isn't the issue.
Given some plausible assumptions about how parameters are passed,
the value of 'a' (97 on an ASCII-based system) will be interpreted by
printf() as if it were a pointer value. So it *might* print characters
starting at memory address 97 until it happens to run into a '\0'.
Or it might die immediately if that address doesn't exist or is
write-protected.
write-protection by itself would have no effect here. read-protection
would and is at least theoretically possible but not so widely used.

Otherwise agree, and with the rest snipped.

- David.Thompson1 at worldnet.att.net
 
K

Keith Thompson

Dave Thompson said:
write-protection by itself would have no effect here. read-protection
would and is at least theoretically possible but not so widely used.

Yes, I meant read-protected -- and an address like 97 very commonly
*is* read-protected (at least protected from reading by any program
without special privileges). A small program I just wrote to read a
byte from address 97 died with a segmentation fault.
 
J

Jordan Abel

write-protection by itself would have no effect here. read-protection
would and is at least theoretically possible but not so widely used.

Except that address could belong to the operating system, and
"read-protection" in terms of protecting memory from being read from
user programs is somewhat more common. Also, the address could simply
not be mapped.
 

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

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top