2014-12-10 1 views
0

это функция, я звоню от основных:Как освободить массив char **, выделенный в функции вызова из основного?

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

И это, как я использую его в основном:

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); 

    } 

Я пытался сделать бесплатно в массив в конце время но он не работает. У меня все еще есть утечка памяти из этой функции (проверка valgrind). Я использую эту функцию, чтобы освободить:

void freeTokens(char** tokens) 
{ 
    while(*tokens != NULL) 
    { 
    *tokens = NULL; 
    free(*tokens); 
    *tokens++; 
    } 
    tokens = NULL; 
    free(tokens); 
} 
+1

Пожалуйста, не масштабируются распределения по 'SizeOf (Char)', это всегда один, так он просто добавляет шум. Кроме того, 'c = (char **) malloc (((wordCount) +1) * sizeof (char *));' гораздо лучше написано как 'c = malloc (((wordCount) + 1) * sizeof * c) ; '. Не выставлять возвращаемое значение 'malloc()' в C] (http://stackoverflow.com/a/605858/28169). – unwind

+0

Сначала освободите его, затем назначьте ему NULL. Подобно этому вы всегда вызываете 'free' с указателем NULL. – Marian

ответ

0

Вы теряете первоначальную стоимость tokens (вещь, которую вы должны освободить) приращение его; то вы установите его на NULL, затем попробуйте бесплатно NULL.

Вместо:

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 
} 
+0

Большое спасибо! Я действительно благодарю вас, что мне очень помогло! –

Смежные вопросы