0

this is the function that i am calling from main:

char** readTokens(char *userInput, const char *seperator)
{
    char** c;
    char line1[512],line2[512];
    int wordCount = 0;
    int index;
    char* tmp;
    strcpy(line1, userInput);

    for (index=0;line1[index]!='\n';index++);

    line1[index]='\0';
    strcpy(line2,line1);
    tmp = strtok(line1,seperator);
    while (tmp!=NULL)
    {
        tmp=strtok(NULL,seperator);
            wordCount = wordCount + 1;
    }
    if((wordCount) == ERROR)
    {
            return NULL;
    }

  c=(char**)malloc(((wordCount)+1)*sizeof(char*));
  if (c == NULL) 
  {
    printf("failed to allocate memory.\n");
    return NULL;
  }

  tmp = strtok(line2,seperator);
  index=0;

  while (tmp!=NULL)
  {
    c[index]=(char*)malloc((strlen(tmp)+1*sizeof(char)));  
    if (c[index]==NULL)
    {
            printf("failed to allocate memory.\n");
            return NULL;   
        }

    strcpy(c[index],tmp);
    tmp=strtok(NULL,seperator);
    index++;
  }

  c[index] = NULL;//put NULL on last place  

  return c;
}

And this how i use it in main:

    while (fgets(words, sizeof(words), filePointer) != NULL) // this line is a command of reading a line from the file.
    {
        /*here i am calling the function*/
        array = readTokens(words, " ");
        theGraph->graphEdges[index_i].sourceVertex = array[ZERO];
        theGraph->graphEdges[index_i].destinationVertex = array[ONE];
        theGraph->graphEdges[index_i].arcValue = atoi(array[TWO]);

        for(index_j = ZERO ; index_j < vertexes ; index_j++)
        {
            if(theGraph->placeInTableIndex[index_j] == NULL)
            {
                theGraph->placeInTableIndex[index_j] = array[ZERO];
                break;  
            }
            else if(strcmp(theGraph->placeInTableIndex[index_j],array[ZERO]) == ZERO)
                break;
        }

        for(index_j = ZERO ; index_j < vertexes ; index_j++)
        {
            if(theGraph->placeInTableIndex[index_j] == NULL)
            {
                theGraph->placeInTableIndex[index_j] = array[ONE];
                break;  
            }
            else if(strcmp(theGraph->placeInTableIndex[index_j],array[ONE]) == ZERO)
                break;
        }
        theGraph->graphEdges[index_i+ONE].sourceVertex = array[ONE];
        theGraph->graphEdges[index_i+ONE].destinationVertex = array[ZERO];
        theGraph->graphEdges[index_i+ONE].arcValue = atoi(array[TWO]);
        index_i+= TWO;
        //freeTokens(array);

  }

I tried to do free to the array in the end of the while but it not work i still have memory leak from this function (valgrind check). i am using this function to free:

void freeTokens(char** tokens)
{
  while(*tokens != NULL)
  {
    *tokens = NULL;
    free(*tokens);
    *tokens++;
  }
  tokens = NULL;
  free(tokens);
}
  • 1
    Please don't scale allocations by `sizeof (char)`, it's always 1 so it just adds noise. Also, `c=(char**)malloc(((wordCount)+1)*sizeof(char*));` is much better written as `c = malloc(((wordCount) + 1) * sizeof *c);`. [Don't cast the return value of `malloc()` in C](http://stackoverflow.com/a/605858/28169). – unwind Dec 10 '14 at 15:36
  • First free it, then assign NULL to it. Like this you are always calling `free` with NULL pointer. – Marian Dec 10 '14 at 15:37

1 Answers1

0

You're losing the original value of tokens (the thing you need to free) by incrementing it; then you set it to NULL, then try to free NULL.

Instead:

void freeTokens(char** tokens)
{
   char **freeTokens = tokens;

   while (*freeTokens != NULL)
   {
     free(*freeTokens);
     *freeTokens = NULL;   // not actually necessary, but must happen *after* if at all
     freeTokens++;        
   }

   free(tokens);
   // tokens = NULL;    // accomplishes nothing; doesn't change the caller's version
}
Paul Roub
  • 36,322
  • 27
  • 84
  • 93