I am trying to enhance the string splitter by splits on :
char. Original version can be found at string splitter - how is it working
I do not want to use MAX_TOKEN_SIZE, I want the buffer to be just enough to hold each token. I added malloc and realloc as follows but I am getting free(): double free detected in tcache 2
error which I do not understand. How am I double freeing ? Thanks for all your help.
PS: Based on Gerhardh's comments, I modified the code as follows, but now I am getting segfault.
PS: Based on user3121023's comments, I added parenthesis around *token in 2 places and it works now.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
# define GROWBY 32
const char* splitter(const char *str, char delimiter, char **token) {
size_t i = 0;
size_t buflen = 32;
while (*str) {
if ( i == buflen) {
buflen = GROWBY;
printf("gowing buffer\n");
char *new_token = realloc(*token, buflen * sizeof **token);
if (new_token == NULL){
fprintf(stderr, "Out of Memory");
abort();
}
*token = new_token; //set the new pointer to old pointer
}
char c = *(str );
if (c == delimiter)
break;
(*token)[i ] = c; //user3121023
}
(*token)[i] = '\0'; /* set the null terminator, user3121023 */
return str;
}
int main(){
const char *env =
"/bin/svsgerertegdfyufdujhdcjxbcn:/sbin:::/usr/bin/46526vw67vxshgshnxxcxhcgbxhcbxn";
while (*env){
char *token = malloc(GROWBY * sizeof(char));
env = splitter(env, ':', &token);
if (token[0] == '\0') {
strcpy(token, "./");
}
printf("%s\n", token) ;
free(token);
}
return 0;
}
CodePudding user response:
Try using strcspn
to advance to the next delimiter.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char* splitter(const char *str, char *delimiter, char **token) {
size_t buflen = 0;
size_t extra = 0;
buflen = strcspn ( str, delimiter); // characters to next delimiter
extra = 1;
if ( ! buflen) {
extra = 3; // need space for "./" copy in main
}
char *new_token = realloc(*token, ( buflen extra) * sizeof **token);
if (new_token == NULL){
fprintf(stderr, "Out of Memory");
abort();
}
*token = new_token; //set the new pointer to old pointer
strncpy ( *token, str, buflen);
(*token)[buflen] = 0;
str = buflen;
if ( *str) {
str = 1;
}
return str;
}
int main(void){
const char *env =
"/bin/svsgerertegdfyufdujhdcjxbcn:/sbin:::/usr/bin/46526vw67vxshgshnxxcxhcgbxhcbxn";
while (*env){
char *token = NULL;
env = splitter(env, ":", &token); // note " instead of '
if (token[0] == '\0') {
strcpy(token, "./");
}
printf("%s\n", token) ;
free(token);
}
return 0;
}