when using qsort() to try and organize an array of pointers I always get garbage on the first element of the double pointer. I have a suspicion that it's pointing to the wrong memory address and I'm just not understanding.
I'm pretty pretty new to C (about 3-4 weeks) and if someone could help me understand why I'm getting the bad value and suggest how I could get around the problem I would appreciate it.
char *token;
char **string_array = calloc(wordcount, sizeof(char));
if (!string_array){
fprintf(stderr, "couldn't make double pointer\n");
}
size_t str_array = 0;
token = strtok(w2->data, "\n\t ");
printf("token %ld: %s\n",str_array, token);
size_t tok_len = strlen(token);
string_array[str_array] = calloc(tok_len,sizeof(char));
if (!string_array[str_array]){
fprintf(stderr, "could not find any of your words\n");
return;
}
if (!strncpy(string_array[str_array++], token, tok_len)){
return;
}
for (int x = 1; x<wordcount; x++){
token = strtok(NULL, "\n\t ");
tok_len = strlen(token);
string_array[str_array] = calloc(tok_len,sizeof(char));
if (!string_array[str_array]){
fprintf(stderr, "failed somewhere with other tokens\n");
return;
}
printf("token %ld: %s\n",str_array, token);
if (!strncpy(string_array[str_array++], token, tok_len)){
puts("could not find one of your words\n");
return;
}
}
qsort(string_array, str_array, sizeof(*string_array), lexsort);
for (int x = 0; x<wordcount; x++){
printf("%s\n",string_array[x]);
}
return;
}
**//shows me what flags the user has set**
a selected
this is the most recent character: a
**//debugging though print statements**
The struct was made
gathering words
Allocated space
** //lines of words read in from file passed on the command line**
token 0: is
token 1: a
token 2: file
token 3: of
token 4: 123:LK
token 5: words
token 6: 123456789
**//output after the array has been sorted**
123456789
123:LK
**//this blank spot is the first element of the array and sometimes it's random garbage from memory (depending on the word)**
a
file
of
words
I thought if I expanded the double pointer array +1 (calloc((wordcount + 1), sizeof(char)) and started added the elements at the first index of the array instead of the zeroth index (str_array = 1;) it might help but it just seg faults (naturally...)
First, double pointers are pointers that point to pointers, so in the calloc
you must use char *
instead of char
and you should remember to initialize inner pointers too, which you actually did here string_array[str_array] = calloc(tok_len,sizeof(char));
.
Second, strings in C are null terminated which means C stores Hello
as H e l l o NULL
so when you have strlen
equals to 5 you need an array of 6 elements to store it.
string_array[str_array] = calloc(tok_len,sizeof(char) + 1);
The following line in your code is correct:
if (!strncpy(string_array[str_array++], token, tok_len)){
return;
}
but it is better to write it as to make more readable:
if (!strncpy(string_array[str_array], token, tok_len)){
return;
}
str_array++;
About the qsort
, I think it is correct and will work as expected. Again, using sizeof(char *)
is more readable than sizeof(*string_array)
.