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;
}
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];