wolfie78uk
Programmer
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;
}
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;
}