heise Security IT security news and services at heise Security UK

// SimpleHeap.cpp 
//
  
#include "stdafx.h"
#include "stdio.h"
#include "windows.h"
  
typedef struct __HeapHdr__ {
  struct __HeapHdr__     *next;
  struct __HeapHdr__     *prev;
  unsigned int        size;
  unsigned int        used;
  // Usable data area starts here
} HeapHdr_t;
  
HeapHdr_t *Init_SimpleHeap( void *memory, unsigned int initial_size) {
  HeapHdr_t      *root;
  
  root = (HeapHdr_t *) memory;
  root->next = NULL;
  root->prev = NULL;
  root->size = initial_size - sizeof(HeapHdr_t);
  root->used = 0;
  
  return root;
}
  
void *SimpleHeap_alloc( size_t s, HeapHdr_t *root ) {
  HeapHdr_t   *p;
  HeapHdr_t   *np;
  
  p = root;
  // run through the whole list of blocks to the end 
  while ( NULL != p ) {
    
    // if this block is not used and large enough 
    if ( (0 == p->used) && (s < p->size + sizeof(HeapHdr_t)) ) {
     
      // a new block is generated for the remaining 
      // free memory and added to the end of the memory to be used
      // in the list
      np = (HeapHdr_t *) ((unsigned char *)p + sizeof(HeapHdr_t) + s);
      // the successor remains the same
      np->next = p->next;
      // the successor of block p now has to refer to the new
      // block np if there is a successor
      if ( NULL != p->next ) 
         p->next->prev = np;
      // The predecessor of np is p
      np->prev = p;
      // the new block is the same size as the memory that is still free 
      // and unused
      np->size = p->size - s - sizeof(HeapHdr_t);
      np->used = 0;
     
      // once the new block has been created for the remaining 
      // memory, the old block can be used
      p->size = s;
      p->used = 1;
      p->next = np;
     
      // the pointer for the usable data area is returned to the 
      // user
      return (void*) ((unsigned char*)p + sizeof(HeapHdr_t) );
    }
    
    // view next block
    p = p->next;
      
  } // while 
    
  // if no useful block is found, the
  // function returns NULL 
  return NULL;
}
  
void SimpleHeap_free( void *userp ) {
  HeapHdr_t   *hdr;
  
  // the pointer transferred to the user is actually a pointer to 
  // hdr->usermem. You can get the correct pointer for hdr by
  // moving the user pointer forwards by the size of the 
  // header
  hdr = (HeapHdr_t *) ( (unsigned char *)userp - sizeof(HeapHdr_t) );
  
  // the following step releases the memory area again
  // so that it can be reused
  hdr->used = 0;
  
  // Tests whether the subsequent block is free
  if ( 0 == hdr->next->used ) {
    // new size of this block from the sum of both
    hdr->size += hdr->next->size + sizeof(HeapHdr_t);
      
    // Now, the next block has to be removed from the doubly
    // linked list. First the prev pointer for the 
    // predecessor of the next block is changed for this block:
    if ( NULL != hdr->next->next )
      hdr->next->next->prev = hdr->next->prev;
    // Now, the current successor is made into the successor of
    // the next block:
    hdr->next = hdr->next->next
    // Now, the block hdr->next is removed from the doubly linked
    // list
  }
}
    
#define HEAP_SIZE ( 4096 * 1024 )
int _tmain(int argc, _TCHAR* argv[])
{
  void     *myHeap;
  HeapHdr_t   *myRoot;
   
  HANDLE    hFile;
  unsigned int   width, height;
  unsigned int   bytesIn;
  unsigned char   *image;
      
  if ( 2 != argc ) 
    {
      fprintf( stderr, "Usage: %s <filename>\n", argv[0] );
      return ( -2 );
    }
      
  if ( NULL == ( myHeap = LocalAlloc( LPTR, HEAP_SIZE ) ) ) 
    {
      fprintf( stderr, "LocalAlloc failed\n");
      return ( -1 );
    }
      
  printf( "Initialize SimpleHeap ...\n" );
  myRoot = Init_SimpleHeap( myHeap, HEAP_SIZE );
      
  // Open file
  if ( INVALID_HANDLE_VALUE == 
       ( hFile = CreateFile( argv[1], FILE_READ_DATA, 0, 0, 
      OPEN_EXISTING, 0, 0 ) ) ) 
    {
      fprintf( stderr, "Failed to open %s\n", argv[1] );
      return ( -3 );
    }
      
  // Read width of image
  if ( ! ReadFile( hFile, &width, sizeof(width), (LPDWORD) &bytesIn, 0 ) ) {
    fprintf( stderr, "Failed to read width from file\n" );
    return ( -4 );
  }
       
  // Read height of image
  if ( ! ReadFile(hFile, &height, sizeof(height), (LPDWORD) &bytesIn, 0 ) ) {
    fprintf( stderr, "Failed to read height from file\n" );
    return ( -5 );
  }
       
  // Reserve memory on SimpleHeap 
  printf("Reserve memory for %u x %u Pixel: %u Bytes\n", width, height, width*height);
  image = ( unsigned char * ) SimpleHeap_alloc( width * height, myRoot );
  printf( "pointer *image = %p\n", image );
       
       
  // Read image
  for ( unsigned int i = 0; i < height; i++ ) {
    // Reserve memory for a line of image
    printf( "Reserve %u bytes for one image line\n", width );
    line = ( unsigned char *) SimpleHeap_alloc( width, myRoot );
    printf( "pointer *line = %p\n", line );
       
    if ( ! ReadFile( hFile, line, width, (LPDWORD) &bytesIn, 0 ) )  {
       fprintf( stderr, "Failed to read image line %u\n", i );
       return ( -6 );
    }
       
    // Copy data to image
    memcpy( image + ( i * width ), line, bytesIn );
    // Release memory again
    SimpleHeap_free( line );
       
    if ( bytesIn != width ) {
        fprintf( stderr, "Short or broken image\n" );
        return ( -7 );
    }
  }
       
  SimpleHeap_free( image );
       
  //
  // end use of memory
  //
  LocalFree( (HLOCAL) myHeap );
  return 0;
}
  • Bookmark & Share
  • digg this
  • submit to slashdot
  • post to delicious
  • StumbleUpon
  • submit to reddit