web-dev-qa-db-ja.com

strtokの結果の文字列を解放する必要がありますか?

むしろ、strtokは、戻り値が指す文字列をどのように生成するのでしょうか。メモリを動的に割り当てますか?次のコードでトークンを解放する必要があるかどうかわからないため、質問しています。

STANDARD_INPUT変数は、割り当て用のメモリが不足し、文字列がテスト対象である場合の終了プロシージャ用です。

int ValidTotal(STANDARD_INPUT, char *str)
{
    char *cutout = NULL, *temp, delim = '#';
    int i = 0; //Checks the number of ladders in a string, 3 is the required number
    temp = (char*)calloc(strlen(str),sizeof(char));
    if(NULL == temp)
        Pexit(STANDARD_C); //Exit function, frees the memory given in STANDARD_INPUT(STANDARD_C is defined as the names given in STANDARD_INPUT)
    strcpy(temp,str);//Do not want to touch the actual string, so copying it
    cutout = strtok(temp,&delim);//Here is the lynchpin - 
    while(NULL != cutout)
    {
        if(cutout[strlen(cutout) - 1] == '_')
            cutout[strlen(cutout) - 1] = '\0'; \\cutout the _ at the end of a token
        if(Valid(cutout,i++) == INVALID) //Checks validity for substring, INVALID is -1
            return INVALID;
        cutout = strtok(NULL,&delim);
        strcpy(cutout,cutout + 1); //cutout the _ at the beginning of a token
    }
    free(temp);
return VALID; // VALID is 1
}
15
Sunspawn

strtok渡した文字列を操作し、その文字列へのポインタを返すため、メモリは割り当てられません。

strsepまたは少なくともstrtok_rを使用して、後で頭痛の種を減らすことを検討してください。

12
Andreas

docs によると:

戻り値

文字列で見つかった最後のトークンへのポインタ。

リターンポインタは、トークンが開始する入力文字列のバイトの1つを指しているだけなので、解放する必要があるかどうかは、入力文字列を割り当てたかどうかによって異なります。

7
qwwqwwq

Strtok(...)関数の最初のパラメーターは[〜#〜] your [〜#〜]string:

str
切り捨てるC文字列。この文字列は、より小さな文字列(トークン)に分割されることによって変更されていることに注意してください。あるいは、ヌルポインターを指定することもできます。その場合、関数は、関数への前回の正常な呼び出しが終了した場所でスキャンを続行します。

'\ 0'文字を[〜#〜] your [〜#〜]文字列に入れ、終了した文字列として返します。 はい、元の文字列をマングルします。後で必要になった場合は、コピーを作成してください。

さらに、定数文字列であってはなりません(例:_char* myStr = "constant string";)._ here を参照してください。

ローカルまたはmalloc/callocによって割り当てることができます。

スタックにローカルで割り当てた場合(例:_char myStr[100];_)、解放する必要はありません。

Mallocで割り当てた場合(例:char* myStr = malloc(100*sizeof(char));)、解放する必要があります。

いくつかのサンプルコード:

_#include <string.h>
#include <stdio.h>
int main()
{
   const char str[80] = "This is an example string.";
   const char s[2] = " ";
   char *token;

   /* get the first token */
   token = strtok(str, s);

   /* walk through other tokens */
   while( token != NULL ) 
   {
      printf( " %s\n", token );

      token = strtok(NULL, s);
   }

   return(0);
}
_

注:この例は、文字列を反復処理する方法を示しています...元の文字列がマングルされたため、strtok(...)は前回の場所を記憶し、文字列を処理し続けます。

5