Question

I'm trying to write a function that inserts into a dictionary (an array of strings), but in alphabetical (lexical) order, but I'm running into an invalid read of size 8 error and I'm not entirely sure why.

Here is my code:

int insertWord(char **array, int *count, char word[])
{
    char *wordPtr;

    wordPtr = (char *)malloc((strlen(word) + 1) * sizeof(char));
    if (wordPtr == NULL)
    {
        fprintf(stderr,"    Malloc of array[%d] failed!\n", *count);
        return -1;
    }
    /* Memory for this word has been allocated, so copy characters
       and insert into array */

    strcpy(wordPtr, word);

    // Iterate through the word array
    // Check if str1 > other strings
    // Lower ascii value = earlier in the alphabet
    // Will return neg value if str1 < str2 (str1 comes before str2)
    // Will return 0 if they are equal
    // Will return pos value if str1 > str2 (str1 comes after str2)
    // Check for an element that comes after the given word in the alphabet
    bool greaterElementFound = false;
    int indexLoc = *count;
    for(int i = 0 ; i < *count ; i ++){
            // If compare is a neg #, that means that wordPtr comes before array[i]
            // So array[i] must be shifted right, and wordPtr must be inserted in its place
            if(strcasecmp(wordPtr, array[i]) < 0){
                    greaterElementFound = true;
                    indexLoc = i;
                    break;
            }
    }
    if(greaterElementFound == true){
            // Account for overwrite of last element
            array[*count+1] = array[*count];
            // Shift all elements over from indexLoc to *count
            for(int i = *count; i > indexLoc; i--){
                    array[i] = array[i-1];
            }
    }
    array[indexLoc] = wordPtr;

    (*count)++;

return 0;
}

I'm getting a suppressed error in valgrind :

==4123== ERROR SUMMARY: 2 errors from 1 contexts (suppressed: 4 from 4)
==4123== 
==4123== 2 errors in context 1 of 1:
==4123== Invalid write of size 8
==4123==    at 0x401056: insertWord (in /import/linux/home/jball2/CLab/lab2)
==4123==    by 0x400E3E: loadArray (in /import/linux/home/jball2/CLab/lab2)
==4123==    by 0x400AAE: main (in /import/linux/home/jball2/CLab/lab2)
==4123==  Address 0x51b1450 is 0 bytes after a block of size 400 alloc'd
==4123==    at 0x4C2779D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4123==    by 0x400D91: loadArray (in /import/linux/home/jball2/CLab/lab2)
==4123==    by 0x400AAE: main (in /import/linux/home/jball2/CLab/lab2)

If anyone could point me in the right direction that would be greatly appreciated, thanks.

-------------------------------------FOR REFERENCE-------------------------------------------
Here is my loadArray() function:

int loadArray(char *inFileName, char ***array, int *count, int *capacity)
{
FILE *inFile;
char word[WORD_LENGTH];  /* this is the ONLY auto array we'll need */

if ((inFile = fopen(inFileName, "r")) == NULL)
{
    fprintf(stderr,"Error opening input file, %s\n", inFileName);
    return -1;
}

*array = (char **)malloc(*capacity * sizeof(char*));
if (*array == NULL)
{
    fprintf(stderr, "Malloc of array in loadArray failed!\n");
    return -1;
}

printf("Reading file %s (each . is 5000 words read)\n", inFileName);

*count = 0;
while (fscanf(inFile, "%s", word) == 1)
{
    if (*count >= *capacity)
    {
    /* call a function that will double the size of the array and copy its contents */
    doubleArray(array, count, capacity);
    }

    if (insertWord(*array, count, word) != 0)
    {
        fprintf(stderr,"    Insert returned an error!\n");
        fclose(inFile);
        return 1;
    }

    if (*count % 5000 == 0)
    {
        printf(".");
        fflush(stdout);  /* stdout is buffered, so have to force flush */
    }
}

fclose(inFile);

return 0;
}
Était-ce utile?

La solution

If *count is the number of elements in array (used and unused) then this

        array[*count+1] = array[*count];

will go beyond the boundaries of array. The array may be index from 0 to *count - 1.

If *count is the number of used elements in array, you need to look at the total size of array before extending.

There are other indexes of array that could be >= *count as well. Look at them all carefully.

If array is malloc'ed in the code that calls insertWord you will need to realloc it to resize array.

In any event, seeing how array is created in the code that calls insertWord is needed to comment intelligently.


Ok, new info. Consider the situation where capacity=100, and count=99, you call insertWord and need to append the new word. This

array[*count+1] = array[*count];

becomes

array[100] = array[99];

That index of 100 is too big; capacity is 100, valid indices are 0-99. You can fix this by changing

if (*count >= *capacity) // double array

to

if (*count >= *capacity-1) // double array
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top