Welcome, Guest. Please login or register.
Amiga Kit Amiga Store Hollywood MAL AMIStore App Store A600 Memory

AuthorTopic: Help bughunt this (a good pointer exercise too)...  (Read 825 times)

0 Members and 1 Guest are viewing this topic.

Offline Jose

Help bughunt this (a good pointer exercise too)...
« on: May 28, 2005, 09:49:54 PM »
After 2 hours I think I'll leave for later or maybe put it up here8-)

This thing is supposed to make up a 256 element array of pointers to BYTE arrays. Each BYTE array is NULL terminated and it's elements contain the flag numbers that would make up the value of the offset from the first element of the array of pointers to the one that points to it. For example
the array of pointer's first element would point to a BYTE array with values 0. The second one to 1,0. The third to 2,0. The fourth 2,1,0  and so on.
Maybe I'm just too hanged over 8-) (not really, unfortunatelly...).
The output is not what I expected, so may the bug hunt begin.
:-x

Code: [Select]
#include <exec/types.h>
#include <exec/memory.h>
#include <stdio.h>
#include <stdlib.h>

#include <clib/exec_protos.h>
#include <clib/alib_protos.h>

BYTE **ByteFlagNrs;
BYTE **ByteFlagNrsPtr;
UBYTE IndexCounter;
BYTE FlagShiftNr;
const UBYTE Comparevalue = 1;
BYTE FlagCounter;
UBYTE *BytePtr;
WORD TestCounter;

 int main (int argc, char **argv)
   { if (!(ByteFlagNrs = ByteFlagNrsPtr = (BYTE **)AllocMem (sizeof (LONG) * 256, MEMF_ANY | MEMF_CLEAR)))
       printf (&quot;Couldn't allocate memory...\n&quot;);
     else
       { if (!(*ByteFlagNrsPtr++ = AllocMem (sizeof (BYTE), MEMF_ANY | MEMF_CLEAR))) /* First table entry is zero */
           printf(&quot;No more memory !!\n&quot;);
         for (IndexCounter = 1; IndexCounter != 0; IndexCounter++) /* Iterate 255 times */
           { if (!(*ByteFlagNrsPtr = AllocMem (sizeof (BYTE) * 8 + 1, MEMF_ANY | MEMF_CLEAR)))
               printf (&quot;No memory !\n&quot;);
             else
               {
                 FlagCounter = 0;
                 for (FlagShiftNr = 0; FlagShiftNr <= 7; FlagShiftNr++)
                   { if ((Comparevalue << FlagShiftNr) & IndexCounter)
                     { *(*ByteFlagNrsPtr + FlagCounter) = FlagShiftNr + 1;
                       FlagCounter++;
                   
                     }
                   }
                 FreeMem ((*ByteFlagNrsPtr++ + FlagCounter), sizeof (BYTE) * 8 + 1 - (FlagCounter));
               }
           }
       }
    /* TEST IT ! */
    ByteFlagNrsPtr = ByteFlagNrs;
    for (TestCounter = 0; IndexCounter <= 255; IndexCounter++)
      {
        BytePtr = *ByteFlagNrsPtr;
        while (*BytePtr)
          { printf (&quot;%u &quot;, *BytePtr++);
          }
        ByteFlagNrsPtr++;
        printf (&quot;   &quot;);

      }
    exit (0);
   }
    :-D
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
  • Total likes: 0
    • http://www.iki.fi/sintonen/
Re: Help bughunt this (a good pointer exercise too)...
« Reply #1 on: May 28, 2005, 10:08:10 PM »
Few things I noticed after 5 mins:

- the style is horrible. the source code is totally unreadable unless if you reformat it.

- you can't FreeMem partial chunks of allocated memory. It might work with certain systems, and fail with others.

- memory allocation and deallocation work with granularity of 8 bytes. if you freemem ptr + 1, you actually end up freeing ptr + 8.

- the memory not freed is taken permanently from the system (until next reboot).

- the test loop (probably) uses wrong variable:
Code: [Select]
for (TestCounter = 0; IndexCounter <= 255; IndexCounter++)
should be:
Code: [Select]
for (TestCounter = 0; TestCounter <= 255; TestCounter++)
 

Offline Jose

Re: Help bughunt this (a good pointer exercise too)...
« Reply #2 on: May 28, 2005, 10:12:17 PM »
@Piru

I updated with a little description with what it should do.

\\"We made Amiga, they {bleep}ed it up\\"
 

Offline Jose

Re: Help bughunt this (a good pointer exercise too)...
« Reply #3 on: May 28, 2005, 10:16:51 PM »
@Piru

 Few things I noticed after 5 mins:

- the style is horrible. the source code is totally unreadable unless if you reformat it.

I know I just wanted to reproduce the problem in shorter piece of code than what I have here as fast as possible.

- you can't FreeMem partial chunks of allocated memory. It might work with certain systems, and fail with others.

Ups... that might explain the weird output then.

- memory allocation and deallocation work with granularity of 8 bytes. if you freemem ptr + 1, you actually end up freeing ptr + 8.

Ahhh!! Yes that might also explain it..
- the memory not freed is taken permanently from the system (until next reboot).  8-)
 :-D

Thanks you rule! I'll to modify it later on with all that in mind.
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
  • Total likes: 0
    • http://www.iki.fi/sintonen/
Re: Help bughunt this (a good pointer exercise too)...
« Reply #4 on: May 28, 2005, 10:44:32 PM »
Yet, while I completely fail to see any purpose for creating such an array, here's what I came up with:

Code: [Select]

#include <exec/types.h>
#include <exec/memory.h>
#include <stdio.h>

#include <proto/exec.h>

int main (int argc, char **argv)
{
  struct entry
  {
    UBYTE b[8];
  } *array;

  /* NOTE: Only the array of the last entry will actually take 9 bytes
   * (since it has all bits set: 7 6 5 4 3 2 1 0. Thus only the last
   * entry needs to have array of 9 bytes. Thus + 1.
   */
  array = AllocMem(sizeof(*array) * 256 + 1, MEMF_ANY);
  if (array)
  {
    int i;

    for (i = 0; i < 256; i++)
    {
      int n, cnt = 0;

      for (n = 8; n >= 0; n--)
      {
        if (i & (1 << n))
        {
          array[i].b[cnt++] = n + 1;
        }
      }
      array[i].b[cnt] = 0;
    }

    /* TEST IT ! */
    for (i = 0; i < 256; i++)
    {
      UBYTE *p = array[i].b;

      printf(&quot;%u: &quot;, i);
      while (*p)
      {
        printf(&quot;%u &quot;, *p++);
      }
      printf(&quot;\n&quot;);
    }

    FreeMem(array, sizeof(*array) * 256 + 1);
  }
  else
  {
    printf(&quot;No more memory !!\n&quot;);
  }

  return 0;
}


I took the liberty of changing the array type for simpler and more efficient code.
 

Offline Karlos

Re: Help bughunt this (a good pointer exercise too)...
« Reply #5 on: May 28, 2005, 11:10:16 PM »
I'm still trying to find the callback or interrupt mechanism that notifies Piru immediately of any coding issue posted on this site ;-)
int p; // A
 

Offline Jose

Re: Help bughunt this (a good pointer exercise too)...
« Reply #6 on: May 29, 2005, 12:41:50 AM »
@Piru
I managed to fix my code (below) but you're too fast for me :-o ... I actually did a small break (no honestly), but took  me about 20 minutes or more. Sometimes I tend to solve my coding problems with flashes after I gave up :lol: ...

By the way, not that it's that usefull but the purpose of that code was to avoid having to check each flag individually, instead one could use a table that promptly gives (after some indirections) the number of the flags that are checked wich then can be used as offsets to access another table with an array of functions to run .


@Karlos

:lol: Yeah..


Anyway, (still without clean up)...:

Code: [Select]
#include <exec/types.h>
#include <exec/memory.h>
#include <stdio.h>
#include <stdlib.h>

#include <clib/exec_protos.h>
#include <clib/alib_protos.h>

BYTE **ByteFlagNrs; /* Ptr to 256 element array of ptrs to BYTE array */
BYTE **ByteFlagNrsPtr; /* Ptr to go through elements of above array */
UBYTE IndexCounter; /* Counter to count till 256 */
BYTE FlagShiftNr;
const UBYTE Comparevalue = 1;
BYTE FlagCounter;
UBYTE *BytePtr;  /* Ptr to go through BYTE array */
WORD TestCounter;

 int main (int argc, char **argv)
   { if (!(ByteFlagNrs = ByteFlagNrsPtr = (BYTE **)AllocMem (sizeof (LONG) * 256, MEMF_ANY | MEMF_CLEAR)))
       printf (&quot;Couldn't allocate memory...\n&quot;);
     else
       { if (!(*ByteFlagNrsPtr++ = AllocMem (sizeof (BYTE), MEMF_ANY | MEMF_CLEAR))) /* First element is zero */
           printf(&quot;No more memory !!\n&quot;);
         else for (IndexCounter = 1; IndexCounter != 0; IndexCounter++) /* Iterate 255 times till 256th element */
           { if (!(*ByteFlagNrsPtr = AllocMem (sizeof (BYTE) * 8 + 1, MEMF_ANY | MEMF_CLEAR)))
               printf (&quot;No memory !\n&quot;);
             else
               {
                 FlagCounter = 0;
                 for (FlagShiftNr = 0; FlagShiftNr <= 7; FlagShiftNr++)
                   { if ((Comparevalue << FlagShiftNr) & IndexCounter)
                     { *(*ByteFlagNrsPtr + FlagCounter) = FlagShiftNr + 1;
                       FlagCounter++;
                   
                     }
                   }
               }
             ByteFlagNrsPtr++;
           }
       }
    /* TEST IT ! */
    ByteFlagNrsPtr = ByteFlagNrs;
    for (TestCounter = 0; TestCounter <= 255; TestCounter++)
      {
        BytePtr = *ByteFlagNrsPtr;
        while (*BytePtr)
          { printf (&quot;%u &quot;, *BytePtr++);
          }
        ByteFlagNrsPtr++;
        printf (&quot;   &quot;);
      }
    exit (0);
   }
   
\\"We made Amiga, they {bleep}ed it up\\"
 

Offline Karlos

Re: Help bughunt this (a good pointer exercise too)...
« Reply #7 on: May 29, 2005, 12:51:10 AM »
Quote

Jose wrote:
Sometimes I tend to solve my coding problems with flashes after I gave up :lol: ...


I thought that was entirely normal procedure :lol: Works for me, anyway.
int p; // A