-1

So I am extremely confused right now. In the following code I initialize a for loop and attempt to decrement a size_t variable. However when doing this it appears that another size_t variable begins to decrement instead.

The code is as follows:

/**
 * sanitize_octet - Sanitizes a given octet for ipv4 calculation
 * requirements.
 *
 * @octet - Octet to be sanitized.
 *
 * returns:
 * NULL pointer - failure
 * Pointer to ret - success
 */
const char *sanitize_octet(const void *octet)
{
        char ret[4];
        size_t i = strlen(octet), j = i;

        if(i > 3) {
                printf("error: '%s' is not a valid octet.", (char *) octet);
                return NULL;
        }
        strcpy(ret, (char *) octet);
        while(i--) {
                if(!isdigit(ret[i])) {
                        printf("error: '%s' is not a valid octet.", ret);
                        return NULL;
                }
                if((int) ret[i] > 255) {
                        printf("error: '%s' is not a valid octet.", ret);
                        return NULL;
                }
        }
        if(j != 3) {
                i = 3 - j;
                for(j = 2; j > 1; j--) {
                        printf("j: %d, i: %d\n", j, i);
                        system("pause");
                }
        }
        puts(ret);
}

The function is still a work in process. What is really confusing me is this the for loop at the bottom. When initialized as for(j = 2; j > 1; j-- it actually decrements i instead of j and will simply execute until it crashes. However if I initialize the loop with j having a different value (e.g. 3) it executes as expected. I've never seen anything like this before and am extremely confused.

Here is a sample console output with j initialized to 2:

j: 2, i: 2
Press any key to continue . . .
1




j: 2, i: 1
Press any key to continue . . .
19

You can clearly see that i is being decremented and not j.

What could possibly be causing this?

UPDATE: Here is the code that causes an infinite loop:

const char *sanitize_octet(const void *octet)
{
        char ret[4];
        size_t i = strlen(octet), j = i;

        if(i > 3) {
                printf("error: '%s' is not a valid octet.", (char *) octet);
                return NULL;
        }
        strcpy(ret, (char *) octet);
        while(i--) {
                if(!isdigit(ret[i])) {
                        printf("error: '%s' is not a valid octet.", ret);
                        return NULL;
                }
                if((int) ret[i] > 255) {
                        printf("error: '%s' is not a valid octet.", ret);
                        return NULL;
                }
        }
        if(j != 3) {
                i = 3 - j;
                for(j = 2; j >= 0; j--) {
                        if(i) {
                                i--;
                        }
                        printf("j: %d, i: %d\n", j, i);
                        system("pause");
                }
        }
        puts(ret);
}

And here is the console output for that exact code:

j: 2, i: 1
Press any key to continue . . .
j: 1, i: 0
Press any key to continue . . .
j: 0, i: 0
Press any key to continue . . .
j: -1, i: 0
Press any key to continue . . .
j: -2, i: 0
Press any key to continue . . .
j: -3, i: 0
Press any key to continue . . .
j: -4, i: 0
Press any key to continue . . .
j: -5, i: 0
Press any key to continue . . .
j: -6, i: 0
Press any key to continue . . .
j: -7, i: 0
Press any key to continue . . .
j: -8, i: 0
Press any key to continue . . .
j: -9, i: 0
Press any key to continue . . .
Keith Miller
  • 1,337
  • 1
  • 16
  • 32

3 Answers3

3

Answer for the first version of your question:

Your output clearly shows that you call sanitize_octet once, get the output

j: 2, i: 2
Press any key to continue . . .
1

and then call sanitize_octet a second time with a different parameter and then get the output

j: 2, i: 1
Press any key to continue . . .
19

Your loop body is executed only once in both of your calls to sanitize_octet and thus neither j nor i is decremented.

Answer for the second version of your question:

j is a size_t, which is an unsigned value. So j>=0 is always true.
Your printf is only obfuscating, because it treats the size_t as a signed int and prints it as if j where declared as int.

Werner Henze
  • 16,404
  • 12
  • 44
  • 69
  • Brain fart oops. Fridays at the office ? :) I do however think at some point in time something *very* strange was going on as the same code (posted abouve) would execute and cause an infinite loop. – Keith Miller May 08 '15 at 15:49
  • I updated my post I am now back to my original problem with my update. – Keith Miller May 08 '15 at 16:00
2

@user3121023's comment is spot on.

Let's simplify the code to:

int j;
for (j = 2; j > 1; j--) {
    printf("j = %d\n", j);
}

You will see similar results... a j = 2 line of output, then nothing more.

Now lets break down the code to remove the for loop and replace it with a goto (for illustrative reasons). This is the same net result:

    j = 2;
loop:
    printf("j = %d\n", j);
    j--;
    if (j > 1) goto loop;

This breakdown makes it obvious why you would only get a single line of output since the loop terminates by decrementing j to 1, failing the if condition.

mah
  • 39,056
  • 9
  • 76
  • 93
0

size_t is unsigned. Hence, although printf prints it with sign, j is always >= 0. You would have to change the type.

JeffRSon
  • 10,404
  • 4
  • 26
  • 51