In association with heise online

// SimpleHeap.cpp 
//
 
#include "stdafx.h"
#include "stdio.h"
#include "windows.h"
 
typedef struct __HeapHdr__ {
<ul class="see-also">
<li>truct __HeapHdr__ *next;</li>
<li>truct __HeapHdr__ *prev;</li>
</ul>
unsigned int size;
unsigned int used;
// Usable data area starts here
} HeapHdr_t;
&nbsp;
HeapHdr_t *Init_SimpleHeap( void *memory, unsigned int initial_size) {
HeapHdr_t *root;
&nbsp;
root = (HeapHdr_t *) memory;
root->next = NULL;
root->prev = NULL;
root->size = initial_size - sizeof(HeapHdr_t);
root->used = 0;
&nbsp;
return root;
}
&nbsp;
void *SimpleHeap_alloc( size_t s, HeapHdr_t *root ) {
HeapHdr_t *p;
HeapHdr_t *np;
&nbsp;
p = root;
// run through the whole list of blocks to the end
while ( NULL != p ) {
&nbsp;
// if this block is not used and large enough
if ( (0 == p->used) && (s < p->size + sizeof(HeapHdr_t)) ) {
&nbsp;
// 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;
&nbsp;
// 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;
&nbsp;
// the pointer for the usable data area is returned to the
// user
return (void*) ((unsigned char*)p + sizeof(HeapHdr_t) );
}
&nbsp;
// view next block
p = p->next;
&nbsp;
} // while
&nbsp;
// if no useful block is found, the
// function returns NULL
return NULL;
}
&nbsp;
void SimpleHeap_free( void *userp ) {
HeapHdr_t *hdr;
&nbsp;
// 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) );
&nbsp;
// the following step releases the memory area again
// so that it can be reused
hdr->used = 0;
&nbsp;
// 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);
&nbsp;
// 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
}
}
&nbsp;
#define HEAP_SIZE ( 4096 * 1024 )
int _tmain(int argc, _TCHAR* argv[])
{
void *myHeap;
HeapHdr_t *myRoot;
&nbsp;
HANDLE hFile;
unsigned int width, height;
unsigned int bytesIn;
unsigned char *image;
&nbsp;
if ( 2 != argc )
{
fprintf( stderr, "Usage: %s <filename>\n", argv[0] );
return ( -2 );
}
&nbsp;
if ( NULL == ( myHeap = LocalAlloc( LPTR, HEAP_SIZE ) ) )
{
fprintf( stderr, "LocalAlloc failed\n");
return ( -1 );
}
&nbsp;
printf( "Initialize SimpleHeap ...\n" );
myRoot = Init_SimpleHeap( myHeap, HEAP_SIZE );
&nbsp;
// 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 );
}
&nbsp;
// Read width of image
if ( ! ReadFile( hFile, &width, sizeof(width), (LPDWORD) &bytesIn, 0 ) ) {
fprintf( stderr, "Failed to read width from file\n" );
return ( -4 );
}
&nbsp;
// Read height of image
if ( ! ReadFile(hFile, &height, sizeof(height), (LPDWORD) &bytesIn, 0 ) ) {
fprintf( stderr, "Failed to read height from file\n" );
return ( -5 );
}
&nbsp;
// 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 );
&nbsp;
&nbsp;
// 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 );
&nbsp;
if ( ! ReadFile( hFile, line, width, (LPDWORD) &bytesIn, 0 ) ) {
fprintf( stderr, "Failed to read image line %u\n", i );
return ( -6 );
}
&nbsp;
// Copy data to image
memcpy( image + ( i * width ), line, bytesIn );
// Release memory again
SimpleHeap_free( line );
&nbsp;
if ( bytesIn != width ) {
fprintf( stderr, "Short or broken image\n" );
return ( -7 );
}
}
&nbsp;
SimpleHeap_free( image );
&nbsp;
//
// end use of memory
//
LocalFree( (HLOCAL) myHeap );
return 0;
}
Print Version | Permalink: http://h-online.com/-747161
  • Twitter
  • Facebook
  • submit to slashdot
  • StumbleUpon
  • submit to reddit
 


  • July's Community Calendar





The H Open

The H Security

The H Developer

The H Internet Toolkit