Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do I perform basic memory management

Status
Not open for further replies.

wolfie78uk

Programmer
Jul 3, 2002
35
GB
Hi,

Having been programming in the sheltered word of .NET for a while, I appear to have forgotten how to perform the most basic of tasks in C and desperately require help.

I want to store a list of words in memory that I can access quickly. Because all of the words will be of different lengths, I thought that I would store all of the words on one heap (the "word" heap) and then store a pointer to each word in the "word" heap in the "dictionary" heap.

My logic was that the "dictionary" heap would store 32 bit memory addresses that I could then 'dereference' to retrieve the corresponding word on the "word" heap. Because all the values on dictionary heap would be the same size, it should be very easy to step through (rather than dealing wih strings of different lengths).

However, I have been plagued by problems. The program reads the words from a file. Small files were OK, but I noticed that over a certin size strange and/or fatal errors began occurring. Therefore, I have stripped the file IO from the program completely and put the code that would usually execute for each word in the file in a FOR loop so that I can check at which point in the loop things go awry.

When the upper bound of the loop is set to a value over 279, the "word heap" address returned from the dictionary heap is incorrect and when the loop upper bound is set to a value over 15895 the program crashes.

I think that I am doing something fundamentally wrong and would appreciate any help.

I have tidied the code up as best I can but please forgive the state of it as it is most definately a "work in progress".

Thanks in advance,

Simon
(code attached)

#include <windows.h>
#include <stdio.h>

//Heap related vatriables :
//-------------------------
HANDLE wordHeap; //Stores words/strings
HANDLE dictionaryHeap; //Stores pointers to the word heap
char ** dictionary; //Block allocated from dictionary heap
char ** words;//Bloack allocated from word heap

//My test word
char * WORD_TO_STORE = "Whywontthiswork";

//Function
char * storeWord (char *);

int main() {

//VARIABLES USED TO OUTPUT WORDS
char ** dicPtr; //Pointer to the address on the "dictionary" heap
char ** wordPtr; // Pointer to the address on the "word" heap
////////////////////////////////

// VARIABLES USED TO STORE WORDS
long i; // Loop counter
int firstBlock; // Pointer to first block of memory allocated on "dictionary" heap
char ** dictionaryWalker; // Used to traverse "dictionary" heap

//ALLOCATE MEMORY
dictionaryHeap = HeapCreate(0,0,0);
wordHeap = HeapCreate (0,0,0);
dictionaryWalker = malloc(sizeof(char*));

// Set flag to rmember to store "first block"
firstBlock = 1;

printf ("Storing words.......\n\n");

//If the loop upper bound is > 279 then the "word ptr" will return an incorrect (odd) address
//If the loop upper bound is > 15895 then we crash :-(
for (i=0; i < 279; i++) {


dictionary = HeapAlloc(dictionaryHeap,0,sizeof(char*));
if (firstBlock == 1) {

memcpy(dictionaryWalker,&dictionary,sizeof(char*));
firstBlock =0;
}

memcpy(dictionary,storeWord(WORD_TO_STORE),sizeof(char *));

}

//Output last word pointer
printf ("\tLast Word ptr : %x\n", *dictionary);

printf ("\n\nRetrieving words.......\n\n");
//This loop should output every address on the "word" heap
while (*dictionaryWalker <= dictionary) {


dicPtr = (char**)dictionaryWalker;
wordPtr = malloc(sizeof(char*));

//THIS IS THE OFFENDING LINE :
memcpy(wordPtr,*dicPtr,sizeof(char*));

*dictionaryWalker += 16; //Minimum heap allocation unit

// If this is the last pointer then dump the word pointer
if (*dictionaryWalker > dictionary) {
printf ("\tLast Word ptr : %x\n",*wordPtr);
}

free(wordPtr);// Cleanup
}

return 0;
}


// Stores a word in the "word" heap and returns a pointer to that
// word
char * storeWord (char * word) {

words = HeapAlloc(wordHeap,0,strlen(word) + 1);
memcpy(words,word,strlen(word) +1);
return &words;
}
 
First of all:
Have a look at the STL vector class. It will do what you want, is a lot easier to use (since someone else already wrote it for you) and these template classes are hard to outperform (they say) since they are already optimized....

Second:
If you insist on reinventing the wheel then openup your memory debug window and see what happens in memory with the two heaps while looping.

Greetings,
Rick
 
Hi Rick,

Thanks for your reply.

My reasoning for using C instead of C++ was that I would get greater speed (I do appreciate that I am reinventing the wheel ;-) ). Do you feel that the difference in performance is negligible? (I am certainly no expert on performance - I am just going on heresay).

Cheers,

Simon
 
There is no reason why well written c++ should be slower than c. Using things like the stl vector class is going to be about as fast as youll be able to write (highly optimised).

Skute

&quot;There are 10 types of people in this World, those that understand binary, and those that don't!&quot;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top