2016-05-02 5 views
-3

どうすればからstrdupへの呼び出しが次のようになったとしますか:*(result + idx++) = strdup(token);strdup後にどのようにフリーズ()できますか?

もっとコンテキスト:

char **str_split(char *a[], char *a_str, const char a_delim) { 
    char **result = 0; 
    size_t count = 0; 
    char *tmp = a_str; 
    char *last_comma = 0; 
    char delim[2]; 
    delim[0] = a_delim; 
    delim[1] = 0; 

    /* Count how many elements will be extracted. */ 
    while (*tmp) { 
     if (a_delim == *tmp) { 
      count++; 
      last_comma = tmp; 
     } 
     tmp++; 
    } 

    /* Add space for trailing token. */ 
    count += last_comma < (a_str + strlen(a_str) - 1); 

    /* Add space for terminating null string so caller 
     knows where the list of returned strings ends. */ 
    count++; 

    result = malloc(sizeof(char *) * count); 
    if (result == NULL) { 
     printf("Error allocating memory!\n"); //print an error message 
     return result; //return with failure 
    } 

    if (result) { 
     size_t idx = 0; 
     char *token = strtok(a_str, delim); 

     while (token) { 
      assert(idx < count); 
      *(result + idx++) = strdup(token); /* memory leak! how to free() */ 
      token = strtok(0, delim); 
     } 
     assert(idx == count - 1); 
     *(result + idx) = 0; 
    } 

    return result; 
} 
+2

'result [idx ++]'があまりにもわかりやすかったと思いますか? – Olaf

+0

'delim [0]'と 'delim [1]'が使われているので、配列インデックス演算子は禁止してはいけません。 – MikeCAT

+1

この関数を呼び出すコードは、格納されたすべてのポインタに対して 'free'を呼び出す必要があります。 –

答えて

2

*(result + idx) = 0;ラインは、シーケンスの終わりがどこにあるか教えすることが可能となります。 ただfree()すべての要素は、それらを使用し終えた後に割り当てられます。 また、自身を格納する配列は、使用終了後にfree()になります。それはresultで行われています

char ** ret = char **str_split(/* some arguments */); 
size_t idx; 

/* deal with the result */ 

for (idx = 0; *(ret + idx) != NULL; idx++) { 
    free(*(ret + idx)); 
} 
free(ret); 
+2

'ret(idx)'を '*(ret + idx) 'よりも使いやすくする –

+0

これで動作するようになりました。私の場合は 'for(idx = 0; *(dealloc [f] + idx)!= NULL; idx ++){'私は配列を持っているためです。 – Montao

1

、この関数を呼び出すコードはresult内のすべてのポインタをfree、その後free結果自体する必要があります。

関連する問題