Thread: anyone bored enough to help me debug some code?

  1. #1
    Registered User
    Join Date
    Jan 2002
    Posts
    552

    anyone bored enough to help me debug some code?

    Ive been working at this for the past day and its driving me wild. Basically, all this code is supposed to do is to take an array of binary data, replace all occurances of 0xff (what I call a 'set byte') with some two-byte value (called the 'expand word'), then restore the array to its original form. The two-byte value is determined by finding a two-byte sequence that is _not_ in the array. This code seems to fail about 1 out of 10 times for reasons unknown. The main function is used to test the functions 'ExpandSetByteInBuffer' and 'RestoreSetByteInBuffer'. The other functions are used within these two. Ive included comments at key areas. Any help will be much appreciated. Oh yeah, by the way, this code is (c) *ClownPimp*

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <time.h>
    
    typedef  unsigned short  USHORT;
    typedef  unsigned char   UCHAR;
    typedef  unsigned int    UINT;
    typedef  unsigned long   ULONG;
    
    typedef  unsigned char   BYTE;
    typedef  unsigned short  WORD;
    typedef  unsigned long   DWORD;
    
    #define  SET_BYTE_EXP_SIZE  2
    
    
    /* generates the two byte sequence by recording all two-byte sequences in the array an picking one from the remaining sequences */
    WORD GenerateExpandWord(BYTE buffer[], UINT bufsize)
    {
        BYTE *p1 = buffer, *p2 = buffer+1;
        UCHAR table[256][256] = {0}; // buffer has a max value of 
                                                         // about 10000, so there must
                                                         // be an unused byte-sequence
    
        for (UINT i = 1; i < bufsize; i++)
            table[*p1++][*p2++] = 1; // record all the byte sequences
    
        for (UINT j = 0; j < 255; j++)
        {
            for (i = 0; i < 255; i++)
            {
                if (table[j][i] == 0) // choose the first unused sequence
                    return (j << 8) | i;
            }
        }
    
        return (WORD)0;  // should never reach here
    }
    
    /* crap, moms gotta use the comp, Ill come back and add some  more comments later (maybe, the code shouldnt be to hard to figure out) */
    
    UINT FindNumSetBytes(BYTE *buf, UINT bufsize)
    {
        UINT k = 0;
        for (UINT i = 0; i < bufsize; i++)
            if (*buf++ == 0xff)  k++;
    
        return k;
    }
    
    USHORT RestoreSetByteInBuffer(BYTE buffer[], UINT buf_bytes, WORD expandWord)
    {
        BYTE *temp_buf, *tbp, *bp = buffer, expWdH, expWdL;
        USHORT k = 0;
    
        expWdH = BYTE(expandWord >> 8); // the high byte
        expWdL = BYTE(expandWord & 0x00ff); // the low byte
        temp_buf = tbp = new BYTE[buf_bytes];
        for (UINT i = 0; i < buf_bytes; i++)
        {
            if (*bp == expWdH && 
                *(bp+1) == expWdL)
            {
                *tbp++ = 0xff;
                bp += 2;
                i++;
            }
            else
            {
                *tbp++ = *bp++;
            }
        }
        k = tbp - temp_buf;
        memcpy(buffer, temp_buf, k);
        delete[] temp_buf;
    
        return k;
    }
    
    USHORT ExpandSetByteInBuffer(BYTE buffer[], UINT bufsize, WORD *expandWord)
    {
        BYTE *temp_buf, *tbp, *bp = buffer, expWdH, expWdL;
        USHORT expSize;
    
        *expandWord = GenerateExpandWord(buffer, bufsize);
        expWdH = BYTE(*expandWord >> 8);
        expWdL = BYTE(*expandWord & 0x00ff);
    
        expSize = bufsize + (SET_BYTE_EXP_SIZE - 1) * FindNumSetBytes(buffer, bufsize);
        temp_buf = tbp = new BYTE[expSize];
    
        for (UINT i = 0; i < bufsize; i++)
        {
            if (*bp == 0xff)
            {
                *tbp++ = expWdH;
                *tbp++ = expWdL;
                bp++;
            }
            else
            {
                *tbp++ = *bp++;
            }
        }
    
        memcpy(buffer, temp_buf, expSize);
        delete[] temp_buf;
    
        return expSize;
    }
    
    int main(int argc, char *argv[])
    {
        srand(time(NULL));
        BYTE buffer[10000], b[5000];
        WORD blockSize, expandWord;
        for(UINT j = 0; j < 500; j++)
        {
            for (UINT i = 0; i < 5000; i++)
                b[i] = buffer[i] = (rand() % 256);
    
            blockSize = ExpandSetByteInBuffer(buffer, 5000, &expandWord);
            blockSize = RestoreSetByteInBuffer(buffer, blockSize, expandWord);
    
            if (memcmp(b, buffer, blockSize) == 0 && blockSize == 5000)
                puts("SUCCESS!");
            else
                puts("FAILURE"); // add breakpoint here
        }
    
        return 0;
    }
    Last edited by *ClownPimp*; 01-18-2002 at 05:12 AM.

  2. #2
    Registered User
    Join Date
    Jan 2002
    Posts
    552
    That is exactly why I cant seem to further my chess skills -- my incompleteness in analyzing a situation. I found the bug in my code and you know what, I actually considered that exact situation, but my analysis only accounted for half of the problem! *sigh* Hopefully one day I will learn...

  3. #3
    Registered User
    Join Date
    Jan 2002
    Posts
    552
    Here we go again! And this time seemingly 1 in 10000 chance of failure lol

  4. #4
    Registered User
    Join Date
    Jan 2002
    Posts
    552
    hmmm, i encountered the bug twice, then i ran another 10, 5000 round trials and no bug, and I didnt even bother to note the seed value of the rand gen....... woe is me

  5. #5
    Registered User
    Join Date
    Jan 2002
    Posts
    552
    anyone know how to turn back the seconds counter -- you know, the value returned by time()?

  6. #6
    Registered User
    Join Date
    Jan 2002
    Posts
    552
    isnt talking to oneself a sign of psychosis?

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Next time, do this

    long seed = time(NULL);
    cout << "Seed this time is << seed << end;
    srand(seed);

    When you next find a test case, you can then hardwire that value into the code for your next run.

    Or perhaps jazz it up with a bit of user interface - do you want to use time as a seed, or do you want to input your own value.

  8. #8
    Registered User
    Join Date
    Jan 2002
    Posts
    552
    Got it! Whew, programming it tough.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  2. True ASM vs. Fake ASM ????
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 04-02-2003, 04:28 AM
  3. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM
  4. Debugging leads to buggy code and longer hours?
    By no-one in forum A Brief History of Cprogramming.com
    Replies: 6
    Last Post: 01-28-2002, 11:14 AM
  5. Replies: 4
    Last Post: 01-16-2002, 12:04 AM