Like Tree1Likes
  • 1 Post By Cat

Segfault using logical OR on for loop.

This is a discussion on Segfault using logical OR on for loop. within the C Programming forums, part of the General Programming Boards category; I've received a segmentation fault in this part of code: Code: for (; str[i] != '

Like Tree1Likes
  • 1 Post By Cat

Thread: Segfault using logical OR on for loop.

' || str[i] != ' ...

  1. #1
    Registered User
    Join Date
    Mar 2013
    Location
    Chiang Mai, Thailand.
    Posts
    9

    Segfault using logical OR on for loop.

    I've received a segmentation fault in this part of code:
    Code:
    for (; str[i] != '\0' || str[i] != ' '; i++)
    {
            result[result_pos] = str[i];
            result_pos++;
    }
    which, should mean:
    Code:
    If str[i] is not equal to NULL character nor ' '; then, keep printing the chars within the word to variable result.
    To understand what the function does, here's the whole code:
    Code:
    static char result[999];
    
    /* char *split_word(const char *str, long n);
     * Splits a string word-by-word. Where N is the word number. */
    char *split_word(const char *str, long n)
    {
        size_t result_pos = 0;
        long scr;
        size_t i = 0;
    
        for (scr = 0; scr < n; scr++)
        {
            for (; str[i] != ' '; i++) ; /* Scrolls forward to the desired word */
            i++; /* Skip one char (the space). */
        }
    
        for (; str[i] != '\0' || str[i] != ' '; i++)
        {
            result[result_pos] = str[i];
            result_pos++;
        }
    
        return result;
    }
    I'm trying to accomplish an easier way round to split string by word than using "strtok_r()". It might sound like "re-inventing the wheel", but... i will try to make it neat later.

    The code looks okay, why would it segfault? how can i fix that?
    Last edited by milo64; 03-09-2013 at 11:03 PM.

  2. #2
    Registered User
    Join Date
    May 2009
    Posts
    2,372
    There is NOTHING that makes this false!

    Code:
    str[i] != '\0' || str[i] != ' '
    If str[i] equals '\0' then it CAN NOT equal a space; therefore it will always be true.

    Tim S.
    "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the Universe is winning." Rick Cook

  3. #3
    Registered User
    Join Date
    Mar 2013
    Location
    Chiang Mai, Thailand.
    Posts
    9
    i don't understand. :/

    i thought it would do:

    str[i] is not equal to '\0'; ========>
    +--------------+
    | Continue loop |
    +--------------+
    str[i] is not equal to ' '; =========>

    so, if both statements are says that str[i] != '\0' nor ' '; then, run code in loop.
    until, str[i] is equal to '\0' or str[i] is equal to ' '; then, stop the loop.
    Last edited by milo64; 03-09-2013 at 11:13 PM.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    5,830
    Quote Originally Posted by milo64 View Post
    Code:
    for (; str[i] != '\0' || str[i] != ' '; i++)
    {
            result[result_pos] = str[i];
            result_pos++;
    }
    which, should mean:
    Code:
    If str[i] is not equal to NULL character nor ' '; then, keep printing the chars within the word to variable result.
    That description is ambiguous and certainly does match what the code unambiguously does.

    The code will keep looping forever. There are no characters for which the terminating condition is false. That means i is continually incremented and will eventually exceed 999 (so, by writing to result[i], the code trashes a random area of memory).

    If str[i] is non-zero, the loop condition is always true (and the second test will not be performed). if str[i] is zero, the test str[i] != 0 will be false so the test str[i] != ' ' will be performed which - since str[i] is zero, otherwise it would not have yielded false for the first test - will always yield true.

    How do you fix it? First describe what the code is intended to do, unambiguously - otherwise you can't hope to code something up and have it reliably work. Find a loop condition that can actually yield a false result, so the loop can terminate.
    Last edited by grumpy; 03-09-2013 at 11:13 PM.
    Right 98% of the time, and don't care about the other 3%.

  5. #5
    Registered User
    Join Date
    Mar 2013
    Location
    Chiang Mai, Thailand.
    Posts
    9
    Quote Originally Posted by grumpy View Post
    That description is ambiguous and certainly does match what the code unambiguously does.

    The code will keep looping forever. There are no characters for which the terminating condition is false. That means i is continually incremented and will eventually exceed 999 (so, by writing to result[i], the code trashes a random area of memory).

    If str[i] is non-zero, the loop condition is always true (and the second test will not be performed). if str[i] is zero, the test str[i] != 0 will be false so the test str[i] != ' ' will be performed which - since str[i] is zero, otherwise it would not have yielded false for the first test - will always yield true.

    How do you fix it? First describe what the code is intended to do, unambiguously - otherwise you can't hope to code something up and have it reliably work. Find a loop condition that can actually yield a false result, so the loop can terminate.
    So, you mean, the != returns the false, so, i should find a kind of loop that would exit if the statement is false? right?

  6. #6
    Cat
    Cat is offline
    Registered User
    Join Date
    May 2003
    Posts
    1,571
    I think the point is, you claim to want to break the loop when the character is neither \0 NOR a space, but that's not the logic you've given. The logic you've given could never return false.

    "Neither A nor B" would, in logical terms, be "not (A or B)".

    "not (A or B)" is completely different from "(not A) or (not B)", which is what you've coded. You might consider DeMorgan's laws helpful:

    !(A || B) = !A && !B
    !(A && B) = !A || !B
    Last edited by Cat; 03-09-2013 at 11:25 PM.
    stahta01 likes this.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    5,830
    No.

    Firstly, your problem is not in the kind of loop. No loop (a for-loop, a while-loop, or a do-while-loop) will ever terminate with that loop condition.

    Second, the problem has nothing to do with the != operator. The != tests can each yield true or false. Your problem is in how you are combining the two tests.

    And, no, I'm not going to be more specific than that. A bit of time spent nutting out the problem will teach you a lot. I've told you what is wrong. You have to find an approach to correct that.
    Right 98% of the time, and don't care about the other 3%.

  8. #8
    Registered User
    Join Date
    Mar 2013
    Location
    Chiang Mai, Thailand.
    Posts
    9
    Anyway, i changed it to this way:
    Code:
    for (;; i++)
        {
            if (str[i] != '\0' && str[i] != ' ')
            {
                result[result_pos] = str[i];
                result_pos++;
            }
            else
                break;
        }
    thanks all for you effort. I was a bit confused.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. logical not !7 logical whaaaa?
    By Charbot in forum C Programming
    Replies: 2
    Last Post: 03-22-2011, 07:19 PM
  2. Logical! Logical! Why do you have to be so Logical?
    By g8ortech14 in forum C Programming
    Replies: 24
    Last Post: 09-20-2010, 02:40 PM
  3. getenv() causes segfault in recv() loop
    By MK27 in forum Networking/Device Communication
    Replies: 3
    Last Post: 12-05-2008, 01:04 PM
  4. logical AND...OR
    By Chaplin27 in forum C++ Programming
    Replies: 2
    Last Post: 02-14-2005, 10:50 AM
  5. Logical And
    By shiju in forum C Programming
    Replies: 6
    Last Post: 01-11-2004, 10:15 AM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21