I get an error that I free an invalid pointer.
consider size as 100 (maximum number of words), and max_str_len
as 50 (max number of letters in a word, doesn't contain '\0'. the function is set to scan a sentence and store every word in words array.
int read_words(char* words[], int size, int max_str_len){
int wordsCounter = 0;
for (int i = 0; i <size; ++i) {
words[i]=(char*)malloc(sizeof(char)*(max_str_len+1));
if(words[i]==NULL){
//in case of failure it frees every word.
for (int j = 0; j <i ; ++j) {
free(words[j]);
}
return MALLOCERROR;
}
for (int j = 0; j <max_str_len+1; ++j) {
if(scanf("%c", &words[i][j])==EOF){
wordsCounter++;
words[i][j]='\0';
if(j<max_str_len)
free(&words[i][j+1]);
return wordsCounter;
}
if (words[i][j]==' ') {
words[i][j] = '\0';
if(j<max_str_len)
free(&words[i][j+1]);
break;
}
}
wordsCounter++;
}
return wordsCounter;
}
I see what's going on here; you're allocating a large buffer, reading into it, and if you didn't need all that space for the word, then you want to give back the memory. That makes sense.
You can't tell the allocator: free starting from position but we can do almost the same thing with realloc()
, which takes a pointer and resizes the array, possibly moving it to a new location. In your case of shortening an array, it should work really well.
Instead of
if (j < max_str_len)
free(&words[i][j+1]); // INVALID
try
if (j < max_str_len)
words[i] = realloc(words[i], j+1); // +1 for the NUL byte
This should do what you're looking for.