Thread: Weird behaviour with comparison operator

  1. #1
    Registered User
    Join Date
    Sep 2016
    Posts
    41

    Weird behaviour with comparison operator

    Hey guys,

    I am getting weird behaviour from a deque experiment I wrote. It's not even that significant; it's a comparison operator.

    Please just focus on the mentioned bug, this is incomplete and I would rather figure out the other problems myself. Thank you.

    Here is the code:


    Code:
    Code:
    /* * File: main.c * Author: medicineman25 * * Created on November 21, 2016, 8:16 PM */ #include <stdio.h> #include <stdlib.h> #include "limits.h" /* * */ int left_arr[127]; int right_arr[127]; int* ptr_arr[256]; void flush_ptr_arr(){ for(int i = 0; i < 256; i++){ ptr_arr[i] = NULL; printf("%d pointer flushed\n", i); } for(int i = 0; i < 256; i++){ left_arr[i] = INT_MIN; printf("left initialized: Value at leftarr [%d] = leftarr [%d] \n", i, left_arr[i]); } for(int i = 0; i < 256; i++){ right_arr[i] = INT_MIN; printf("right initialized: Value at rightarr [%d] = rightarr [%d] \n", i, right_arr[i]); } } int* check_left(int* left_ptr){ printf("This is the check left function executing\n"); if(*left_ptr == INT_MIN){ <<<<<<<<<----------------------------<<<<<<<< printf("else: left array pointer = %d\n", left_arr[*left_ptr]); return left_ptr; } else { printf("else cond. in check left left_ptr = %p \n", left_ptr); left_ptr += 1; check_left(left_ptr); } return left_ptr; } int* check_right(int* right_ptr){ if(right_arr[*right_ptr] == INT_MIN){ printf("%d", right_arr[*right_ptr]); return right_ptr; } else { right_ptr += 1; printf("else in check right"); check_right(right_ptr); } return right_ptr; } int* push_left(int* index, int* a){ left_arr[*index] = *a; printf("%d", left_arr[*index]); return &left_arr[*index]; } int* push_right(int* index, int* b){ left_arr[*index] = *b; printf("%d", right_arr[*index]); return &right_arr[*index]; } /* int* check_ptr_array(int* ptr_array_index){ if(ptr_arr[*ptr_array_index] == NULL){ return ptr_array_index; } else { ptr_array_index += 1; check_ptr_array(ptr_array_index); } } */ int main(int argc, char** argv) { flush_ptr_arr(); int value = 7; printf("This is inside the main loop just before check_left_ptr\n"); int* check_left_ptr = check_left(&left_arr[0]); if(check_left_ptr != NULL){ printf("check_left_ptr = %p\n", check_left_ptr); int* left_arr_index = push_left(check_left_ptr, &value); } else { int* check_right_ptr = check_right(&right_arr[0]); if(check_right_ptr != NULL) push_right(check_right_ptr, &value); } return (EXIT_SUCCESS); }


    the logic is simple:

    Code:
    if(value){
      check the left and right arrays;
         if(INT_MIN){
           stop iterating and return the address of that member, then push a value        to that address;
         } else { keep iterating until you find space for a new value;}
    }
    Here's the weird part: This following if statement won't evaluate to true.

    Code:
    Code:
    if(*left_ptr == INT_MIN){ <<<<<<<<<----------------------------<<<<<<<< printf("else: left array pointer = %d\n", left_arr[*left_ptr]); return left_ptr; } else { printf("else cond. in check left left_ptr = %p \n", left_ptr); left_ptr += 1; check_left(left_ptr); }


    It did for a little bit but now again for no reason; it won't. So I tried all differing variations; two are as follows:

    Code:
    Code:
    if(*left_ptr == INT_MIN){ <<<<<<<<<----------------------------<<<<<<<< printf("else: left array pointer = %d\n", left_arr[*left_ptr]); return left_ptr; } else { printf("else cond. in check left left_ptr = %p \n", left_ptr); left_ptr += 1; check_left(left_ptr); }
    became:

    Code:
    Code:
    if(*left_ptr != INT_MIN){ <<<<<<<<<----------------------------<<<<<<<< printf("else: left array pointer = %d\n", left_arr[*left_ptr]); return left_ptr; } else { printf("else cond. in check left left_ptr = %p \n", left_ptr); left_ptr += 1; check_left(left_ptr); }


    Then the else statement would execute?????!!!!!! Which it should, because *left_ptr has been initialized as INT_MIN. But I don't want it to do that, I am trying to use INT_MIN as a way to check empty space. Why did the if statement not evaluate to true the first time??

    I tried to simply switch the bodies of the if and else statements with eachother... this is where it get's REALLY wierd!! .... The if AND else statement stopped executing!!! ... if you think that's bad, hold on to your hats ladies and gentlemen because it's about to get spooky-action-at-a-distance in here; IF I then changed the comparison operator BACK to ==... (with the bodies of each conditional swapped)... all of a sudden the IF statement starts evaluating to true... i.e. like this:

    Code:
    Code:
    if(*left_ptr == INT_MIN){ <<<<<<<<<----------------------------<<<<<<<< printf("else cond. in check left left_ptr = %p \n", left_ptr); left_ptr += 1; check_left(left_ptr); } else { printf("else: left array pointer = %d\n", left_arr[*left_ptr]); return left_ptr; }
    WTF IS GOING ON!!!

    Is this somehow short-circuiting in a way that I am not yet aware?

    NOTE: This DID start working for some reason, after I re-arranged like the above. However I finished where I started, nothing had actually been changed.

    I'm using Netbeans on Arch.

    Thanks in advance!
    MedicineMan25

    p.s. I also tried changing my compiler chain, updating the software and restarting the pc. nothing worked.
    Last edited by MedicineMan25; 12-05-2016 at 07:19 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,064
    > for(int i = 0; i < 256; i++)
    Your program is screwed before you even begin.
    Your arrays have only 127 elements.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Sep 2016
    Posts
    41
    Found the problem... at least for now... INT_MIN was not equal to the value within the array. Even though it was initialized as that value, for some reason I needed to explicitly put the value of -2147... in the if conditional.

    If someone has any insight as to why this has occured, I would be most grateful.

    Thanks again,
    MedicineMan25

  4. #4
    Registered User
    Join Date
    Sep 2016
    Posts
    41
    Holy ........ Salem. I can't believe I didn't see that. Thanks.

    I'll try using the INT_MIN keyword in the conditional now and see if my over-iteration was the problem.

  5. #5
    Registered User
    Join Date
    Sep 2016
    Posts
    41
    Nope... INT_MIN was definitely the problem... weird...

  6. #6
    Registered User
    Join Date
    Sep 2016
    Posts
    41
    Oops, I seem to have generated a seg fault. Damnit.

    Thanks anyway!

  7. #7
    Registered User
    Join Date
    Jun 2015
    Posts
    1,643
    You ignore the return values of the recursive calls in check_left, check_right and check_ptr_array.
    BTW, limits.h should be in angle brackets, not quotes.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,064
    Perhaps you should post your latest code, to see if there is anything else obvious.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Sep 2016
    Posts
    41
    Quote Originally Posted by algorism View Post
    You ignore the return values of the recursive calls in check_left, check_right and check_ptr_array.
    BTW, limits.h should be in angle brackets, not quotes.
    I don't understand that to be a problem. It's quite common to ignore a return value is it not? Is there another way that I could recursively call a function, that eventually returns a value?

    Here is the current code:

    Code:
    /*
     * To change this license header, choose License Headers in Project Properties.
     * To change this template file, choose Tools | Templates
     * and open the template in the editor.
     */
    
    
    /* 
     * File:   main.c
     * Author: medicineman25
     *
     * Created on November 21, 2016, 8:16 PM
     */
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include "limits.h"
    
    
    /*
     * 
     */
    
    
    int left_arr[127];
    int right_arr[127];
    
    
    int* ptr_arr[256];
    
    
    
    
    void flush_ptr_arr(){
           
            for(int i = 0; i < 256; i++){
                ptr_arr[i] = NULL;
                printf("%d pointer flushed\n", i);
            }
            
            for(int i = 0; i < 127; i++){
                left_arr[i] = INT_MIN;
                printf("left initialized: Value at leftarr [%d] = leftarr [%d] \n", i, left_arr[i]);
            }
            
            for(int i = 0; i < 127; i++){
                right_arr[i] = INT_MIN;
                printf("right initialized: Value at rightarr [%d] = rightarr [%d] \n", i, right_arr[i]);
            }
    }
    
    
    int* check_left(int* left_ptr){
        
        printf("This is the check left function executing\n");
        if(*left_ptr == INT_MIN){ 
            
            printf("else: left array pointer = %d\n", left_arr[*left_ptr]);
            return left_ptr;  
            
        } else {                               
            
            printf("else cond. in check left left_ptr = %p \n", left_ptr);
            left_ptr += 1;
            check_left(left_ptr);
    
    
        }
        
        return left_ptr;
    }
    
    
    int* check_right(int* right_ptr){
        
        if(right_arr[*right_ptr] == INT_MIN){
            printf("%d", right_arr[*right_ptr]);
            return right_ptr;
        } else {
            right_ptr += 1;
            printf("else in check right");
            check_right(right_ptr);
        }
        return right_ptr;
    }
    
    
    int* push_left(int* index, int* a){
        
        left_arr[*index] = *a;
        printf("%d", left_arr[*index]);
        return &left_arr[*index]; 
    }
    
    
    int* push_right(int* index, int* b){
        
        left_arr[*index] = *b;
        printf("%d", right_arr[*index]);
        return &right_arr[*index];
    }
    
    
    /*
    int* check_ptr_array(int* ptr_array_index){
        
        if(ptr_arr[*ptr_array_index] == NULL){
            return ptr_array_index;
        } else {
            ptr_array_index += 1;
            check_ptr_array(ptr_array_index);
        }
        
    }
     */
    
    
    
    
    int main(int argc, char** argv) {
    
    
        flush_ptr_arr();
        
        int value = 7;
        
        printf("This is inside the main loop just before check_left_ptr\n");
        int* check_left_ptr = check_left(left_arr);
        
        if(check_left_ptr != NULL){
            printf("check_left_ptr = %p\n", check_left_ptr);
            int* left_arr_index = push_left(check_left_ptr, &value);
        } else {
            int* check_right_ptr = check_right(&right_arr[0]);
          if(check_right_ptr != NULL)
            push_right(check_right_ptr, &value);
        }
        
        return (EXIT_SUCCESS);
    }

  10. #10
    Registered User
    Join Date
    Sep 2016
    Posts
    41
    It seems to be segfaulting no matter what. However this way:

    Code:
    printf("This is the check left function executing\n");
        if(*left_ptr == INT_MIN){ 
            
            printf("else cond. in check left left_ptr = %p \n", left_ptr);
            left_ptr += 1;
            check_left(left_ptr);
    
    
            
        } else {                               
            
            
            printf("else: left array pointer = %d\n", left_arr[*left_ptr]);
            return left_ptr;  
            
        }
    segfaults AFTER recursively calling until the end of the array i.e. the if conditional evaluates to true repeatedly until the end of the array at which point it segfaults for obvious reasons: their is a INT_MIN value at the end of the array, thus it keeps iterating of the end of the array. NOT what I want.

    Whereas this way:

    Code:
    printf("This is the check left function executing\n");
        if(*left_ptr == INT_MIN){ 
            
    
            printf("else: left array pointer = %d\n", left_arr[*left_ptr]);
            return left_ptr;  
                    
    
        } else {                               
            
            printf("else cond. in check left left_ptr = %p \n", left_ptr);
            left_ptr += 1;
            check_left(left_ptr);
    
    
        }

    Segfaults at the point that the if conditional evaluates. Which indicates that I am dereferencing either a void pointer or a pointer to an address that holds no meaning. I am going to attempt debugging with some tools as per this post on cprogramming.com: Debugging Segmentation Faults and Pointer Problems - Cprogramming.com

    Any suggestions in the meantime, are welcome.

  11. #11
    Registered User
    Join Date
    Jun 2015
    Posts
    1,643
    Quote Originally Posted by MedicineMan25 View Post
    I don't understand that to be a problem. It's quite common to ignore a return value is it not?
    That's a non sequitur. Bugs are common, too. So what? You're saying that it's a common thing for you to ignore the return value of your own functions? Why bother having a return value then?

    Is there another way that I could recursively call a function, that eventually returns a value?
    Yes. Don't ignore the return value. Try the following program. Can you fix it? As is, it always prints 0. Why?
    Code:
    #include <stdio.h>
    
    int sum(int n, int s) {
        if (n != 0)
            sum(n - 1, s + n);   // ignoring return value
        return s;
    }
    
    int main() {
        printf("%d\n", sum(10, 0));
        return 0;
    }

  12. #12
    Registered User
    Join Date
    Sep 2016
    Posts
    41
    Quote Originally Posted by algorism View Post
    That's a non sequitur. Bugs are common, too. So what? You're saying that it's a common thing for you to ignore the return value of your own functions? Why bother having a return value then?
    haha, yes that is certainly true...

    Well I want to eventually return a value from the function. All return values up until that point, made recursively, are just garbage. But I see your point, perhaps that return value is more useful than I previously thought.

    Yes. Don't ignore the return value. Try the following program. Can you fix it? As is, it always prints 0. Why?

    Code:
    #include <stdio.h>
    
    int sum(int n, int s) {
        if (n != 0)
             sum(n - 1, s + n);   // ignoring return value
        return s;
    }
    
    int main() {
        printf("%d\n", sum(10, 0));
        return 0;
    }
    That's a good one. It shouldn't, it should return 55 or something. Ah but in recursive we are still returning the value to the caller, which is the previous recursive... not main...

    Code:
    #include <stdio.h>
    
    int sum(int n, int s) {
        printf("%d\n", s);
        if (n != 0)
             s = sum(n - 1, s + n);   // ignoring return value
        return n;
    }
    
    int main() {
        printf("%d\n", sum(10, 0));
        return 0;
    }
    This outputs:

    [quote]

    0
    10
    19
    27
    34
    40
    45
    49
    52
    54
    55
    10

    which ultimately prints 10... but that's not the result your are looking for...

    Code:
    #include <stdio.h>
    
    int sum(int n, int s) {
        printf("%d\n", s);
        if (n != 0)
             s = sum(n - 1, s + n);   // ignoring return value
        return s;
    }
    
    int main() {
        printf("%d\n", sum(10, 0));
        return 0;
    }
    is the answer

  13. #13
    Registered User
    Join Date
    Sep 2016
    Posts
    41
    So your saying that I should be storing a value as the recursion occurs, then pass that value back through as a parameter of the function...

  14. #14
    Registered User
    Join Date
    Jun 2015
    Posts
    1,643
    Quote Originally Posted by MedicineMan25 View Post
    So your saying that I should be storing a value as the recursion occurs, then pass that value back through as a parameter of the function...
    By George, I think he's got it!

  15. #15
    Registered User
    Join Date
    Sep 2016
    Posts
    41
    That's actually really cool, I never really thought about it that way.

    Here is the revised code:

    Code:
    /*
     * To change this license header, choose License Headers in Project Properties.
     * To change this template file, choose Tools | Templates
     * and open the template in the editor.
     */
    
    
    /* 
     * File:   main.c
     * Author: access
     *
     * Created on November 21, 2016, 8:16 PM
     */
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include "limits.h"
    
    
    /*
     * 
     */
    
    
    int left_arr[127];
    int right_arr[127];
    
    
    int* ptr_arr[256];
    
    
    
    
    void flush_ptr_arr(){
           
            for(int i = 0; i < 256; i++){
                ptr_arr[i] = NULL;
                printf("%d pointer flushed\n", i);
            }
            
            for(int i = 0; i < 127; i++){
                left_arr[i] = INT_MIN;
                printf("left initialized: Value at leftarr [%d] = leftarr [%d] \n", i, left_arr[i]);
            }
            
            for(int i = 0; i < 127; i++){
                right_arr[i] = INT_MIN;
                printf("right initialized: Value at rightarr [%d] = rightarr [%d] \n", i, right_arr[i]);
            }
    }
    
    
    int* check_left(int* left_ptr){
        if(*left_ptr != INT_MIN)
            left_ptr = check_left(++left_ptr);
            return left_ptr;  
        
            //printf("else cond. in check left left_ptr = %p \n", left_ptr);
            //left_ptr += 1;
    }
    
    
    int* check_right(int* right_ptr){
        
        if(right_arr[*right_ptr] == INT_MIN)
            right_ptr = check_right(++right_ptr);
        return right_ptr;
    }
    
    
    int* push_left(int* index, int* a){
        
        left_arr[*index] = *a;
        printf("%d", left_arr[*index]);
        return &left_arr[*index]; 
    }
    
    
    int* push_right(int* index, int* b){
        
        left_arr[*index] = *b;
        printf("%d", right_arr[*index]);
        return &right_arr[*index];
    }
    
    
    /*
    int* check_ptr_array(int* ptr_array_index){
        
        if(ptr_arr[*ptr_array_index] == NULL){
            return ptr_array_index;
        } else {
            ptr_array_index += 1;
            check_ptr_array(ptr_array_index);
        }
        
    }
     */
    
    
    
    
    int main(int argc, char** argv) {
    
    
        flush_ptr_arr();
        
        int value = 7;
        
        
        printf("This is inside the main loop just before check_left_ptr\n");
        int* check_left_ptr = check_left(&left_arr[0]); //<<<<<<<---------- I need a second parameter here, perhaps this should be used to dynamically check the pointer array?
        
        if(check_left_ptr != NULL){
            printf("check_left_ptr = %p\n", check_left_ptr);
            int* left_arr_index = push_left(check_left_ptr, &value);
        } else {
            int* check_right_ptr = check_right(&right_arr[0]);
          if(check_right_ptr != NULL)
            push_right(check_right_ptr, &value);
        }
        
        return (EXIT_SUCCESS);
    }
    I'm still getting a segfault but it's now after the check_left function returns an address. So that's ok for tonight.

    Thanks for your insight!!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. StretchDIBits() - weird behaviour..
    By lobo in forum Windows Programming
    Replies: 13
    Last Post: 10-04-2010, 11:23 PM
  2. Weird export macro behaviour.
    By g4j31a5 in forum Windows Programming
    Replies: 10
    Last Post: 06-28-2010, 12:26 AM
  3. weird behaviour with abs()
    By crazyinlove in forum C Programming
    Replies: 19
    Last Post: 02-28-2010, 12:58 AM
  4. Replies: 16
    Last Post: 04-20-2008, 01:15 PM
  5. VC++ 2005 Express: Weird Behaviour
    By psychopath in forum Tech Board
    Replies: 2
    Last Post: 06-21-2006, 07:47 PM

Tags for this Thread