1

複数の文字区切り文字で文字列を分割するコードを作成しました。

この関数を初めて呼び出すときは問題なく動作しています

しかし、2回目に呼び出すと、不要な記号を含む正しい単語が返されます。

この問題は、バッファをクリアしていないために発生していると思います。多くのことを試しましたが、これを解決できません。この問題を解決するのを手伝ってください。

char **split(char *phrase, char *delimiter) {
    int i = 0;
    char **arraylist= malloc(10 *sizeof(char *));
    char *loc1=NULL;
    char *loc=NULL;
    loc1 = phrase;
    while (loc1 != NULL) {
    loc = strstr(loc1, delimiter);
    if (loc == NULL) {
            arraylist[i]=malloc(sizeof(loc1));
            arraylist[i]=loc1;
            break;
    }
    char *buf = malloc(sizeof(char) * 256);    // memory for 256 char
    int length = strlen(delimiter);
    strncpy(buf, loc1, loc-loc1);
    arraylist[i]=malloc(sizeof(buf));
    arraylist[i]=buf;
    i++;
    loc = loc+length;
    loc1 = loc;
}
return arraylist;
}

この関数を初めて呼び出した

char **splitdetails = split("100000000<delimit>0<delimit>hellooo" , "<delimit>");

それは与えます

splitdetails[0]=100000000
splitdetails[1]=0
splitdetails[2]=hellooo

しかし、私はこれに二度目に電話しました

char **splitdetails = split("20000000<delimit>10<delimit>testing" , "<delimit>");

splitdetails[0]=20000000��������������������������
splitdetails[1]=10����
splitdetails[2]=testing

アップデート:-

@fatelerror に感謝します。コードを次のように変更しました

    char** split(char *phrase, char *delimiter) {
    int i = 0;
    char **arraylist = malloc(10 *sizeof(char *));
    char *loc1=NULL;
    char *loc=NULL;
    loc1 = phrase;
    while (loc1 != NULL) {
    loc = strstr(loc1, delimiter);
    if (loc == NULL) {
            arraylist[i]=malloc(strlen(loc1) + 1);
            strcpy(arraylist[i], loc1);
            break;
    }
    char *buf = malloc(sizeof(char) * 256);    // memory for 256 char
    int length = strlen(delimiter);
    strncpy(buf, loc1, loc-loc1);
    buf[loc - loc1] = '\0';
    arraylist[i]=malloc(strlen(buf));
    strcpy(arraylist[i], buf);
    i++;
    loc = loc+length;
    loc1 = loc;
   }
}  

呼び出し元関数では、次のように使用しました

char *id
char **splitdetails = split("20000000<delimit>10<delimit>testing" , "<delimit>");
id = splitdetails[0];
//some works done with id
//free the split details with this code.
for(int i=0;i<3;i++) {
    free(domaindetails[i]);
}free(domaindetails);
domaindetails=NULL;    

次に、2番目に同じものを呼び出しました。

char **splitdetails1= split("10000000<delimit>1000<delimit>testing1" , "<delimit>");

エラーが発生し、関数を解放できません。

前もって感謝します。

4

1 に答える 1

3

あなたの問題は、次の 3 つの基本的な事柄に要約されます。

  1. sizeofではありませんstrlen()
  2. 割り当ては、C の文字列をコピーしません。
  3. strncpy()文字列を常にヌルで終了するとは限りません。

だから、あなたが次のようなことを言うとき:

arraylist[i]=malloc(sizeof(loc1));
arraylist[i]=loc1;

これは文字列をコピーしません。最初のものは のサイズを割り当てます。loc1これはchar *です。つまり、ポインターのサイズを割り当てました。文字列を格納するためにストレージを割り当てたい、つまり以下を使用しstrlen()ます:

arraylist[i]=malloc(strlen(loc1) + 1);

+ 1nul ターミネータ用のスペースも必要なので、 にも注意してください。次に、使用する文字列をコピーするにはstrcpy():

strcpy(arraylist[i], loc1);

あなたが持っていた方法は、古い文字列にポインタを割り当てるだけでした(そして、割り当てたばかりのメモリを解放するプロセスで)。strdup()これらのステップの両方を組み合わせて使用​​することも一般的です。

arraylist[i] = strdup(loc1);

これは便利ですがstrdup()、公式の C ライブラリには含まれていません。コードの使用を検討する前に、コードの移植性のニーズを評価する必要があります。

さらに、 を使用すると、常にヌル終了するとは限らないstrncpy()ことに注意する必要があります。

strncpy(buf, loc1, loc-loc1);

これにより、元の文字列よりも少ないバイトがコピーされ、終了しませんbuf。したがって、自分で nul ターミネータを含める必要があります。

buf[loc - loc1] = '\0';

これがゴミの根本的な原因です。あなたはヌル終了しなかったので、Cはあなたの文字列がどこで終わっているのかわからないので、メモリ内にあるものは何でも読み続けます。

于 2013-03-14T05:51:10.263 に答える