0
votes

I'm in troubles with valgrind and C. I don't know why, but valgrind say this:

==18241== Invalid read of size 1

==18241== at 0x4C31A64: strcmp (vg_replace_strmem.c:846)

==18241== by 0x403110: lastLetters (diccionario.c:1330)

==18241== Address 0x520c5b3 is 0 bytes after a block of size 3 alloc'd

==18241== at 0x4C2DBF6: malloc (vg_replace_malloc.c:299)

==18241== by 0x402ED0: lastLetters (diccionario.c:1284)

I have a dynamic matrix with linked lists where each row is a letter and each column is a word. In the nodes of the lists there are words that I want to compare between them, but just compare the last 3 letters of each one.

Example of the matrix:

Black Blue Blondie BlackOut

Green Grey

Water

Crimsom Color Clue

For example Blue & Clue have the same last 3 letters: lue.

This is my code, and valgrind says that:

line 1284 => lastLettersList = malloc(sizeof(char)*3);

line 1330 => if (strcmp(lastLettersList,lastLettersList2) == 0)

char* lastLettersList;
char* lastLettersList2;
int wordLen = 0;
int maxCount = 0;
int count = 0;

for (int i = 0; i < matrixSpanish->rows; ++i)
{
    node* current = matrixSpanish->list[i]->start;
    while(current!=NULL)
    {
        wordLen = strlen(current->word); 
        count = 0;
        if( wordLen > 2)
        {
            lastLettersList = malloc(sizeof(char)*3);
            lastLettersList[2] = current->word[wordLen-1];
            lastLettersList[1] = current->word[wordLen-2];
            lastLettersList[0] = current->word[wordLen-3];
        }
    }

    for (int j = 0; j < matrixSpanish->rows; ++j)
    {
        node* current2 = matrixSpanish->list[j]->start;             
        while(current2!=NULL)
        {
            wordLen = strlen(current2->word); 
            if( wordLen > 2)
            {
                lastLettersList2 = malloc(sizeof(char)*3);
                lastLettersList2[2] = current2->word[wordLen-1];
                lastLettersList2[1] = current2->word[wordLen-2];
                lastLettersList2[0] = current2->word[wordLen-3];
            }

            if (strcmp(lastLettersList,lastLettersList2) == 0)
            {
                count++;
            }   

            current2=current2->nextNode;
        }
    }    
    current=current->nextNode;
}
1
Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a minimal reproducible example.Stargateur
Did you know that string in C must be nul terminated ?Stargateur
@Stargateur I'll try to make better question in future, many thanks. Yes I know it, but i forget it in this case, that was the problem, thanks again.user6875715

1 Answers

0
votes

You're not allocating enough space for the substrings you're copying. lastLettersList doesn't contain a terminating null byte (nor did you allocate space for it), so it's technically not a string but an array of characters.

You then try to use the string function strcmp on lastLettersList, which is not a string, and you read off the end of the array, which is what Valgrind is warning about. Reading past the end of an array invokes undefined behavior.

Allocate one extra byte for lastLettersList and put the null byte at the end.

lastLettersList = malloc(sizeof(char)*4);
lastLettersList[3] = 0;
lastLettersList[2] = current->word[wordLen-1];
lastLettersList[1] = current->word[wordLen-2];
lastLettersList[0] = current->word[wordLen-3];