Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #94282 > unrolled thread

while(source[i] != '\n' || source[i] != '\0') segmentation fault

Started byalla.rashitova@gmail.com
First post2016-09-30 05:23 -0700
Last post2016-09-30 09:34 -0700
Articles 12 — 9 participants

Back to article view | Back to comp.lang.c


Contents

  while(source[i] != '\n' || source[i] != '\0') segmentation fault alla.rashitova@gmail.com - 2016-09-30 05:23 -0700
    Re: while(source[i] != '\n' || source[i] != '\0') segmentation fault Alla _ <modelling.data@gmail.com> - 2016-09-30 05:27 -0700
    Re: while(source[i] != '\n' || source[i] != '\0') segmentation fault Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-30 14:22 +0100
      Re: while(source[i] != '\n' || source[i] != '\0') segmentation fault mark.bluemel@gmail.com - 2016-09-30 06:37 -0700
        Re: while(source[i] != '\n' || source[i] != '\0') segmentation fault Alla _ <modelling.data@gmail.com> - 2016-09-30 07:49 -0700
        Re: while(source[i] != '\n' || source[i] != '\0') segmentation fault Keith Thompson <kst-u@mib.org> - 2016-09-30 09:16 -0700
          Re: while(source[i] != '\n' || source[i] != '\0') segmentation fault Jerry Stuckle <jstucklex@attglobal.net> - 2016-09-30 14:41 -0400
      Re: while(source[i] != '\n' || source[i] != '\0') segmentation fault Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-30 06:59 -0700
      Re: while(source[i] != '\n' || source[i] != '\0') segmentation fault Alla _ <modelling.data@gmail.com> - 2016-09-30 07:46 -0700
        Re: while(source[i] != '\n' || source[i] != '\0') segmentation fault Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-30 16:04 +0100
    Re: while(source[i] != '\n' || source[i] != '\0') segmentation fault Ken Brody <kenbrody@spamcop.net> - 2016-09-30 10:55 -0400
    Re: while(source[i] != '\n' || source[i] != '\0') segmentation fault Barry Schwarz <schwarzb@dqel.com> - 2016-09-30 09:34 -0700

#94282 — while(source[i] != '\n' || source[i] != '\0') segmentation fault

Fromalla.rashitova@gmail.com
Date2016-09-30 05:23 -0700
Subjectwhile(source[i] != '\n' || source[i] != '\0') segmentation fault
Message-ID<75ada694-4a58-4f1d-81d1-9490a709e75d@googlegroups.com>
Hello!

I don't understand why I get segmentation fault on my while loop
while(source[i] != '\n' || source[i] != '\0')
when i use it to run through the line, which is stored in an array. 

I store the word in char line[] by using the function get_line()

// getline: get line into s, return length
int get_line(char line[], int max)
{
    int c, i;
    i = 0;
    while (--max > 0 && (c = getchar()) != EOF &&
           c != '\n')
        line[i++] = c;
    if (c == '\n')
        line[i++] = c;
    line[i] = '\0';
    
    return i;
}

The get_line function returns the index of the null terminating character in the line[].
If the newline is entered after the user finished entering letters, then the newline is stored, and 
only then the null terminating character. 

Therefore, the entry "should\n" will be stored as:
0 s
1 h
2 0
3 u
4 l
5 d
6 '\n'
7 '\0'

So i = 7 and line[6] = '\n', line[7] = '\0'.

But if I didn't enter '\n', then
0 s
1 h
2 0
3 u
4 l
5 d
6 '\0'
i = 6 and line[6] = '\0'.

Next I would like to loop till the end of the line[] by using the while loop, and compute
the last index. I loop till there is a newline (because I need only letters), or, if there is no
newline, till the null terminating character:

    int i = 0;
    while(source[i] != '\n' || source[i] != '\0')
        i++;
    return i;
If the entry is "should\n":

source[0] = 's'
source[1] = 'h'
source[2] = 'o'
source[3] = 'u'
source[4] = 'l'
source[5] = 'd'
source[6] = '\n' and here the loop stops, no need to evaluate the second condition.

But if the entry is "should":
source[0] = 's'
source[1] = 'h'
source[2] = 'o'
source[3] = 'u'
source[4] = 'l'
source[5] = 'd'
source[6] = '\0' the first condition is false but the second is true and the loop terminates,
returning i = 6

Why do I get a segmentation fault?
Thank you!

[toc] | [next] | [standalone]


#94283

FromAlla _ <modelling.data@gmail.com>
Date2016-09-30 05:27 -0700
Message-ID<9cffb81a-c389-4378-87e4-2685686bab8d@googlegroups.com>
In reply to#94282
Oops, posted this thread using the wrong email address. 

[toc] | [prev] | [next] | [standalone]


#94287

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-09-30 14:22 +0100
Message-ID<871t01a5fo.fsf@bsb.me.uk>
In reply to#94282
alla.rashitova@gmail.com writes:

> I don't understand why I get segmentation fault on my while loop
> while(source[i] != '\n' || source[i] != '\0')
> when i use it to run through the line, which is stored in an array.

A loop ends when it's condition is false, so *every time you write a loop*
negate the condition and check that what you get is indeed the state of
affairs that you want to bring about.

To negate a condition, you need to know two rules called De Morgan's
laws.  They state that the "not of an or is the and of the nots"

  !(A || B)  ==  !A && !B

and the "not of and and is the or of the nots":

  !(A && B)  ==  !A || !B

so your loop it trying to bring about a state in which

  source[i] != '\n' || source[i] != '\0'

is false, i.e.

  !(source[i] != '\n' || source[i] != '\0')

De Morgran tell us that this means

  !(source[i] != '\n') && !(source[i] != '\0')

and we may as well turn !(X != Y) into X == Y while we are at it:

  source[i] == '\n' && source[i] == '\0'

So your loop is trying to make source[i] be both newline and null at the
same time.  It won't ever be able to do that no matter what it does.
The loop can never end (unless it's got a break, goto or return in it).

The problem comes from human language.  People often say things like "if
it's not too hot or too cold" but this does translate into formal logic
as

  !(too_hot(temperature) || too_cold(temperature))

There is an implied extra "not" in the phrase: "if it's not too hot or
(it is) not too cold" making it

  !too_hot(temperature) || !too_cold(temperature)

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#94290

Frommark.bluemel@gmail.com
Date2016-09-30 06:37 -0700
Message-ID<4f17ee9b-c20e-4395-becb-ae79dd7cb987@googlegroups.com>
In reply to#94287
On Friday, 30 September 2016 14:22:11 UTC+1, Ben Bacarisse  wrote:
> alla.rashitova@gmail.com writes:
> 
> > I don't understand why I get segmentation fault on my while loop
> > while(source[i] != '\n' || source[i] != '\0')
> > when i use it to run through the line, which is stored in an array.
> 
> A loop ends when it's condition is false, so *every time you write a loop*
> negate the condition and check that what you get is indeed the state of
> affairs that you want to bring about.

If Ben has to explain this to you after all this time, you are still trying
to go to fast and you are still not doing enough debugging with a piece of paper.

[toc] | [prev] | [next] | [standalone]


#94298

FromAlla _ <modelling.data@gmail.com>
Date2016-09-30 07:49 -0700
Message-ID<10decfab-927d-48d5-8905-c593391008a1@googlegroups.com>
In reply to#94290
<snip>
> If Ben has to explain this to you after all this time, you are still trying
> to go to fast and you are still not doing enough debugging with a piece of paper.

I am very thankful to Ben for detailed explanations and his tremendous help in my learning process. 
This time it was my huge inattentiveness that caused the problem - I should have noticed that I 
used the same index. 

[toc] | [prev] | [next] | [standalone]


#94308

FromKeith Thompson <kst-u@mib.org>
Date2016-09-30 09:16 -0700
Message-ID<lnoa35qs6k.fsf@kst-u.example.com>
In reply to#94290
mark.bluemel@gmail.com writes:
> On Friday, 30 September 2016 14:22:11 UTC+1, Ben Bacarisse  wrote:
>> alla.rashitova@gmail.com writes:
>> 
>> > I don't understand why I get segmentation fault on my while loop
>> > while(source[i] != '\n' || source[i] != '\0')
>> > when i use it to run through the line, which is stored in an array.
>> 
>> A loop ends when it's condition is false, so *every time you write a loop*
>> negate the condition and check that what you get is indeed the state of
>> affairs that you want to bring about.
>
> If Ben has to explain this to you after all this time, you are still
> trying to go to fast and you are still not doing enough debugging with
> a piece of paper.

I've been programming for a long time.  I have yet to stop making silly
little mistakes now and then.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#94318

FromJerry Stuckle <jstucklex@attglobal.net>
Date2016-09-30 14:41 -0400
Message-ID<nsmbjo$v7j$1@jstuckle.eternal-september.org>
In reply to#94308
On 9/30/2016 12:16 PM, Keith Thompson wrote:
> mark.bluemel@gmail.com writes:
>> On Friday, 30 September 2016 14:22:11 UTC+1, Ben Bacarisse  wrote:
>>> alla.rashitova@gmail.com writes:
>>>
>>>> I don't understand why I get segmentation fault on my while loop
>>>> while(source[i] != '\n' || source[i] != '\0')
>>>> when i use it to run through the line, which is stored in an array.
>>>
>>> A loop ends when it's condition is false, so *every time you write a loop*
>>> negate the condition and check that what you get is indeed the state of
>>> affairs that you want to bring about.
>>
>> If Ben has to explain this to you after all this time, you are still
>> trying to go to fast and you are still not doing enough debugging with
>> a piece of paper.
> 
> I've been programming for a long time.  I have yet to stop making silly
> little mistakes now and then.
> 

Ditto here.  And my students would stare at their code for several
minutes, trying to spot what was wrong.  When they finally asked for
help, I would usually take one glance at it and show them where their
problem was.

They'd wonder how I spotted it so fast, and I'd tell them once they've
made that same mistake as many times as I have, they'll see it right
away, also. :)

And I still make those same beginning mistakes at times!

-- 
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================

[toc] | [prev] | [next] | [standalone]


#94293

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2016-09-30 06:59 -0700
Message-ID<edaa2273-38c0-469f-ae67-3e21dbcbde47@googlegroups.com>
In reply to#94287
On Friday, September 30, 2016 at 2:22:11 PM UTC+1, Ben Bacarisse wrote:
>
> To negate a condition, you need to know two rules called De Morgan's
> laws.  They state that the "not of an or is the and of the nots"
> 
>   !(A || B)  ==  !A && !B
> 
> and the "not of and and is the or of the nots":
> 
Rather knotty to follow that law.

[toc] | [prev] | [next] | [standalone]


#94297

FromAlla _ <modelling.data@gmail.com>
Date2016-09-30 07:46 -0700
Message-ID<ce36989e-5a6a-4afd-8381-332ca0ee60e5@googlegroups.com>
In reply to#94287
<snip>
Thank you very much for your reply! I see that my mistake has nothing to do 
with my understanding of logical operators (thank goodness I have no issues
with those), but with my usual habit (which is unfortunately still there) of not
seeing my simple mistakes - of course, if the source[i] = '\n',
then the source[i+1] = '\0', not source[i]. 
Sorry!

[toc] | [prev] | [next] | [standalone]


#94303

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-09-30 16:04 +0100
Message-ID<878tu98m46.fsf@bsb.me.uk>
In reply to#94297
Alla _ <modelling.data@gmail.com> writes:

> <snip>
> Thank you very much for your reply! I see that my mistake has nothing to do 
> with my understanding of logical operators (thank goodness I have no issues
> with those), but with my usual habit (which is unfortunately still there) of not
> seeing my simple mistakes - of course, if the source[i] = '\n',
> then the source[i+1] = '\0', not source[i].

What I advised is a general strategy.  Please apply it to your new
condition and you will see that it is still wrong (though in a very
different way).

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#94301

FromKen Brody <kenbrody@spamcop.net>
Date2016-09-30 10:55 -0400
Message-ID<nsluce$esp$1@dont-email.me>
In reply to#94282
On 9/30/2016 8:23 AM, alla.rashitova@gmail.com wrote:
> Hello!
>
> I don't understand why I get segmentation fault on my while loop
> while(source[i] != '\n' || source[i] != '\0')
> when i use it to run through the line, which is stored in an array.
[...]
>     while(source[i] != '\n' || source[i] != '\0')
>         i++;
[...]

Under what circumstance will the while condition be false?

-- 
Kenneth Brody

[toc] | [prev] | [next] | [standalone]


#94309

FromBarry Schwarz <schwarzb@dqel.com>
Date2016-09-30 09:34 -0700
Message-ID<ur3tublhrnf80m2ks5ikla5hmk3lhimmd2@4ax.com>
In reply to#94282
On Fri, 30 Sep 2016 05:23:47 -0700 (PDT), alla.rashitova@gmail.com
wrote:

>Hello!
>
>I don't understand why I get segmentation fault on my while loop
>while(source[i] != '\n' || source[i] != '\0')
>when i use it to run through the line, which is stored in an array. 
>
>I store the word in char line[] by using the function get_line()
>
>// getline: get line into s, return length
>int get_line(char line[], int max)
>{
>    int c, i;
>    i = 0;
>    while (--max > 0 && (c = getchar()) != EOF &&
>           c != '\n')
>        line[i++] = c;
>    if (c == '\n')
>        line[i++] = c;
>    line[i] = '\0';
>    
>    return i;
>}

Do you realize this function is operationally identical to the
standard library function fgets (except for the error checking)?

>The get_line function returns the index of the null terminating character in the line[].
>If the newline is entered after the user finished entering letters, then the newline is stored, and 
>only then the null terminating character. 
>
>Therefore, the entry "should\n" will be stored as:
>0 s
>1 h
>2 0
>3 u
>4 l
>5 d
>6 '\n'
>7 '\0'
>
>So i = 7 and line[6] = '\n', line[7] = '\0'.
>
>But if I didn't enter '\n', then
>0 s
>1 h
>2 0
>3 u
>4 l
>5 d
>6 '\0'
>i = 6 and line[6] = '\0'.
>
>Next I would like to loop till the end of the line[] by using the while loop, and compute
>the last index. I loop till there is a newline (because I need only letters), or, if there is no
>newline, till the null terminating character:

Since get_line returned the index of the '\0', why are you looping to
find it again?  Why not simply use the value that was returned to you?

>    int i = 0;
>    while(source[i] != '\n' || source[i] != '\0')

After changing the second subscript to i+1 as you indicated
down-thread, what does i signify?  In the first sample input (below),
i would be the index of the '\n'.  In the second sample input, i would
be the index of the 'd'.  The only consistency is that i is the index
of the character before the '\0'.  You could get this simply be
decrementing the value returned by get_line.

If there is a '\n' in the array, you are guaranteed it will always be
the character immediately preceding the '\0'.  If for some reason you
really need this loop instead of the value returned by get_line, then
changing the while expression to use only the second (updated)
comparison produces the exact same results with half the work.

So the real question we have is: what are attempting to do that cannot
be done more straight forwardly?

>        i++;
>    return i;

What function is this code in that are returning the same index that
get_line returned minus 1?

>If the entry is "should\n":
>
>source[0] = 's'
>source[1] = 'h'
>source[2] = 'o'
>source[3] = 'u'
>source[4] = 'l'
>source[5] = 'd'
>source[6] = '\n' and here the loop stops, no need to evaluate the second condition.
>
>But if the entry is "should":
>source[0] = 's'
>source[1] = 'h'
>source[2] = 'o'
>source[3] = 'u'
>source[4] = 'l'
>source[5] = 'd'
>source[6] = '\0' the first condition is false but the second is true and the loop terminates,
>returning i = 6
>
>Why do I get a segmentation fault?

Doesn't your compiler provide a debugger?

-- 
Remove del for email

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web