D
DSF
Hello all,
The following code is driving me crazy. I'm sure the problem with
it must be obvious but I can't see it.
Basically, this code searches any given file for and ASCII 'words'
it can find and stores each word in a dynamically allocated char array
pointed to by a dynamically allocated array of pointers to char*. The
program will crash while freeing the char array.
A few notes.
I have not been able to make it crash using a file that produces a
small number of 'words' (< 70,000).
Setting ALLOCSIZE to larger than the total number of 'words' found
(so the realloc section is never called) seems to prevent the crash.
If I use a file that produces a very large number of 'words'
(>300,000), realloc will fail upon trying to allocate approximately
1.2M of memory. However, realloc succeeds if I replace "allocsize *
sizeof(char *)" with a much larger number, such as 10 million.
Changing ALLOCSIZE will change the array index number where the crash
ocurrs.
Thanks for any help,
DSF
The source:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define BUFFERSIZE 128
#define ALLOCSIZE 100
#define MINWORDLEN 3
#define MAXWORDLEN 20
int main(void)
{
FILE *iptr;
int i, c;
int allocsize = ALLOCSIZE;
int minwordlen = MINWORDLEN;
int maxwordlen = MAXWORDLEN;
int wordcount;
char buffer[BUFFERSIZE];
char **words, **temp;
if(maxwordlen > BUFFERSIZE)
maxwordlen = BUFFERSIZE - 1;
if((iptr = fopen("filename", "rb")) == NULL)
return 1;
words = malloc(allocsize * sizeof(char *));
if(words == NULL)
{
fclose(iptr);
return 3;
}
wordcount = 0;
i = fgetc(iptr);
while(i != EOF)
{
if(isalpha(i))
{
/* get 'word' */
c = 0;
do
{
buffer[c] = (char)tolower(i);
i = fgetc(iptr);
c++;
if(c >= BUFFERSIZE)
break;
} while(isalpha(i) && i != EOF);
buffer[c] = 0;
/*allocate / store current 'word' */
if(strlen(buffer) >= minwordlen && strlen(buffer) <= maxwordlen)
{
words[wordcount] = malloc(strlen(buffer) + 1);
if(words[wordcount] == NULL)
{
for(i = 0; i < wordcount; i++)
free(words);
free(words);
fclose(iptr);
return 3;
}
strcpy(words[wordcount], buffer);
wordcount++;
/* realloc section */
if(wordcount >= allocsize)
{
allocsize += ALLOCSIZE;
temp = realloc(words, allocsize * sizeof(char *));
if(temp == NULL)
{
for(i = 0; i < wordcount; i++)
free(words);
free(words);
fclose(iptr);
return 3;
}
words = temp;
}
/* end realloc section */
}
}
else
{
do
{
i = fgetc(iptr);
} while(!isalpha(i) && i != EOF);
}
}
fclose(iptr);
/* printf added to test code to see which free() index crashes */
for(i = 0; i < wordcount; i++)
{
printf("i: %05d\t%s\n", i, words);
free(words);
}
free(words);
return 0;
}
The following code is driving me crazy. I'm sure the problem with
it must be obvious but I can't see it.
Basically, this code searches any given file for and ASCII 'words'
it can find and stores each word in a dynamically allocated char array
pointed to by a dynamically allocated array of pointers to char*. The
program will crash while freeing the char array.
A few notes.
I have not been able to make it crash using a file that produces a
small number of 'words' (< 70,000).
Setting ALLOCSIZE to larger than the total number of 'words' found
(so the realloc section is never called) seems to prevent the crash.
If I use a file that produces a very large number of 'words'
(>300,000), realloc will fail upon trying to allocate approximately
1.2M of memory. However, realloc succeeds if I replace "allocsize *
sizeof(char *)" with a much larger number, such as 10 million.
Changing ALLOCSIZE will change the array index number where the crash
ocurrs.
Thanks for any help,
DSF
The source:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define BUFFERSIZE 128
#define ALLOCSIZE 100
#define MINWORDLEN 3
#define MAXWORDLEN 20
int main(void)
{
FILE *iptr;
int i, c;
int allocsize = ALLOCSIZE;
int minwordlen = MINWORDLEN;
int maxwordlen = MAXWORDLEN;
int wordcount;
char buffer[BUFFERSIZE];
char **words, **temp;
if(maxwordlen > BUFFERSIZE)
maxwordlen = BUFFERSIZE - 1;
if((iptr = fopen("filename", "rb")) == NULL)
return 1;
words = malloc(allocsize * sizeof(char *));
if(words == NULL)
{
fclose(iptr);
return 3;
}
wordcount = 0;
i = fgetc(iptr);
while(i != EOF)
{
if(isalpha(i))
{
/* get 'word' */
c = 0;
do
{
buffer[c] = (char)tolower(i);
i = fgetc(iptr);
c++;
if(c >= BUFFERSIZE)
break;
} while(isalpha(i) && i != EOF);
buffer[c] = 0;
/*allocate / store current 'word' */
if(strlen(buffer) >= minwordlen && strlen(buffer) <= maxwordlen)
{
words[wordcount] = malloc(strlen(buffer) + 1);
if(words[wordcount] == NULL)
{
for(i = 0; i < wordcount; i++)
free(words);
free(words);
fclose(iptr);
return 3;
}
strcpy(words[wordcount], buffer);
wordcount++;
/* realloc section */
if(wordcount >= allocsize)
{
allocsize += ALLOCSIZE;
temp = realloc(words, allocsize * sizeof(char *));
if(temp == NULL)
{
for(i = 0; i < wordcount; i++)
free(words);
free(words);
fclose(iptr);
return 3;
}
words = temp;
}
/* end realloc section */
}
}
else
{
do
{
i = fgetc(iptr);
} while(!isalpha(i) && i != EOF);
}
}
fclose(iptr);
/* printf added to test code to see which free() index crashes */
for(i = 0; i < wordcount; i++)
{
printf("i: %05d\t%s\n", i, words);
free(words);
}
free(words);
return 0;
}