segmentation fault

D

dough

Can anyone tell me why I get a segmentation fault with the following
code and call?

char *strlwr(char *s)
{
while( s != NULL && *s != '\0' )
{
*s = tolower(*s);
s++;
}

return s;
}

printf("%s", strlwr("HAPPY"));
 
G

Gordon Burditt

Can anyone tell me why I get a segmentation fault with the following
code and call?

Attempting to write on a character in a quoted string constant
invokes the wrath of undefined behavior. The compiler is
permitted to place such data in ROM or memory where write is
not allowed.
printf("%s", strlwr("HAPPY"));

Gordon L. Burditt
 
A

A. Sinan Unur

Can anyone tell me why I get a segmentation fault with the following
code and call?

char *strlwr(char *s)
{
while( s != NULL && *s != '\0' )
{
*s = tolower(*s);
s++;
}

return s;
}

printf("%s", strlwr("HAPPY"));

This is a FAQ:

http://www.eskimo.com/~scs/C-faq/q16.6.html

Also, functions with the str prefix are in reserved by the standard.

Note that the function above will return a pointer to the terminating nul
character.

#include <ctype.h>
#include <stdio.h>

char *mystrlwr(char *s) {
if (s) {
char *t = s;
while (*t) {
*t = tolower((unsigned char) *t);
++t;
}
}
return s;
}

int main(void) {
char s[] = "HELLO";
printf("%s\n", mystrlwr(s));
return 0;
}

D:\Home> gcc -Wall s.c -o s.exe

D:\Home> s
hello
 
D

dough

thank you for that. it cleared a few of my questions.

what happens if i need s to be a pointer because i don't know how big
the string is:

char *s;
while( fscanf(f, "%s", s) != EOF )
{
printf("%s", mystrlwr(s));
}

Is there some kind of malloc() that i need to do as well?
 
J

James McIninch

It's not the function, it's that you return and address that is past the end
of the string.
 
U

uououo

#include <stdio.h>
#include <ctype.h>

char *strlwr(char *s)
{
if( s ){
char *t=s;
for(; *t; ++t)
( *t >= 'A' && *t <= 'Z' ? *t-='A'-'a':0 );
}
return s;
}

int main()
{
char array[]="HAPPY123";
printf("%s", strlwr(array));

return 0;
}
 
A

Artie Gold

James McIninch wrote:
[top posting corrected]
> It's not the function, it's that you return and address that is past the end
> of the string.
>

Erm, no. See elsethread. [It's in the attempt to modify a string literal
-- invoking undefined behavior.] Besides, the returned pointer would be
pointing to the terminating null character of the string. Even
derefencing it would be OK (assuming it *was*, in fact a proper C string).

--ag
 
M

Martin Ambuhl

dough said:
Can anyone tell me why I get a segmentation fault with the following
code and call?

Because you are trying to modify a string literal.
(You are also improperly invading the implementation's namespace by
using the identifier 'strlwr' to name your function. Stop it.)

This question and variations on it have been asked so often that
whenever it is asked it signals that the questioner has not bothered to
follow simple usenet etiquette. It is expected that a civilized poster
to usenet will have
a) checked the FAQ before posting,
b) followed the newsgroup before posting,
c) checked the archives before posting.
That you could ask your question shows that you have done *none* of the
above.
 
A

A. Sinan Unur

thank you for that.

Thank who for what? Please quote an appropriate amount of context.
it cleared a few of my questions.

what happens if i need s to be a pointer because i don't know how big
the string is:

Are you trying to get the whole program written by others?
char *s;
while( fscanf(f, "%s", s) != EOF )
{
printf("%s", mystrlwr(s));
}

Is there some kind of malloc() that i need to do as well?

1. s is pointing to garbage.
2. But more importantly, there is no amount of memory you can allocate
for s that would not be susceptible to being overflowed.

In the case of dealing with whole files, I would be inclined to keep
things simple, and use fgetc.

Sinan

PS: Please read the whole FAQ in its entirety at least once.
 
F

Frodo Baggins

This is a bit off the track the rest of the ppl in this thread are on.
However I think this is useful.
For any case of "Segmentation fault" , compile the prog with (in gcc)
with
-Wall (enables all warnings) and -g (generates debug info) switches
enabled.
Then run the executable under gdb.
That usually pinpoints the source of the segFault.
Regards,
Frodo Baggins
 
F

Flash Gordon

Frodo Baggins wrote:

Please don't top post. Your reply belongs *under* the text you are
replying to.
This is a bit off the track the rest of the ppl in this thread are on.

Please don't use contractions like ppl, they make your post harder to
read for no good reason.
However I think this is useful.
For any case of "Segmentation fault" , compile the prog with (in gcc)
with
-Wall (enables all warnings) and -g (generates debug info) switches
enabled.

<OT>
You should also use "-ansi -pedantic -O" with gcc and some people
recommend -W as well.
<OT>

There are GNU mailing lists where you can get more help on this
including the reason for adding -O.

However, there was no indication in what you quoted that the OP was
using gcc. I've used a number of other compilers under systems that can
produce a "segmentation fault".
Then run the executable under gdb.
That usually pinpoints the source of the segFault.

This only works some of the time, undefined behaviour can often lead to
a crash a long way down the line such as when freeing memory.

You should also redirect people to other groups when you start
discussing the specifics of particular systems since they are not on
topic here beyond the odd example to illustrate a point.
 
J

Joe Wright

dough said:
Can anyone tell me why I get a segmentation fault with the following
code and call?

char *strlwr(char *s)
{
while( s != NULL && *s != '\0' )
{
*s = tolower(*s);
s++;
}

return s;
}

printf("%s", strlwr("HAPPY"));

First, the anonymously defined array "HAPPY" is not guaranteed
writeable. The segfault might be in the strlwr() function.

But then you return s from strlwr(). s points to the terminating NUL of
"HAPPY" (or maybe "happy"). What do you expect printf() to do with that?
 

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,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top