1

いくつかのライブラリ関数が使用されている古いプログラムがありますが、そのライブラリはありません。

だから私はc++のライブラリを使ってそのプログラムを書いています。その古いコードには、このように呼ばれる関数があります

* string = newstrdup( "一部の文字列がここに表示されます");

文字列変数はchar**stringとして宣言されています。

「newstrdup」という名前の関数で彼は何をしているのでしょうか。私は多くのことを試みましたが、彼が何をしているのかわかりません...誰か助けてもらえますか

4

6 に答える 6

4

この関数は、c-string のコピーを作成するために使用されます。これは、文字列リテラルの書き込み可能なバージョンを取得するために必要になることがよくあります。それら (文字列リテラル) 自体は書き込み可能ではないため、このような関数はそれらを割り当てられた書き込み可能なバッファーにコピーします。strtok次に、トークン化する必要がある文字列に書き込むなど、指定された引数を変更する関数にそれらを渡すことができます。

new strdupと呼ばれるので、次のようなものを思いつくことができると思います。

char * newstrdup(char const* str) {
    char *c = new char[std::strlen(str) + 1];
    std::strcpy(c, str);
    return c;
}

文字列を使用して一度解放することになっています

delete[] *string;

それを書く別の方法は、を使用することですmalloc。ライブラリが古い場合は、C++ が C から継承したものを使用している可能性があります。

char * newstrdup(char const* str) {
    char *c = (char*) malloc(std::strlen(str) + 1);
    if(c != NULL) {
        std::strcpy(c, str);
    }
    return c;
}

freeここで、完了したら次を使用して文字列を解放することになっています。

free(*string);

C++ で記述している場合は、最初のバージョンを優先してください。ただし、既存のコードfreeでメモリの割り当てを再度解除する場合は、2 番目のバージョンを使用してください。NULL2 番目のバージョンは、文字列の複製に使用できるメモリがない場合に戻りますが、その場合、最初のバージョンは例外をスローすることに注意してください。NULLに引数を渡すときの動作について、もう 1 つ注意する必要がありますnewstrdup。ライブラリによって、許可される場合と許可されない場合があります。したがって、必要に応じて上記の関数に適切なチェックを挿入してください。strdupPOSIX システムで availableと呼ばれる関数がありますが、その関数は引数を許可せず、演算子 new を使用してメモリを割り当てNULLません。C++

とにかく、私はグーグルのコードサーチでnewstrdup関数を調べたところ、かなりの数が見つかりました。多分あなたのライブラリは結果の中にあります:

Google CodeSearch、newstrdup

于 2009-03-09T04:36:53.290 に答える
3

彼らが「新しい」バージョンの strdup を作成したのには理由があるはずです。したがって、別の方法で処理するコーナーケースが必要です。おそらくヌル文字列は空の文字列を返します。

litb の答えは strdup の代わりです、彼らがしたことには理由があると思います。

strdup を直接使用する場合は、新しいコードを記述するのではなく、define を使用して名前を変更してください。

于 2009-03-09T04:59:37.747 に答える
1

ライン*string = newstrdup("Some string goes here");は に変なところはありませんnewstrdupstringタイプがある場合はchar **、期待どおりnewstrdupに返さchar *れます。おそらく、結果が配置されるstringタイプの変数を指すようにすでに設定されています。char *それ以外の場合、コードは初期化されていないポインターを介して書き込みます..

于 2010-06-27T13:50:18.713 に答える
0

newstrdupは、渡された文字列の複製である新しい文字列を作成している可能性があります。文字列へのポインタを返します(これ自体が文字へのポインタです)。

于 2009-03-09T04:33:27.277 に答える
0

彼は、既存のポインターを操作するために、おそらくそれを新しいサイズに再割り当てしてからその内容を埋めるために、strdup()関数を作成したようです。おそらく、彼はこれを行って、* stringが頻繁に変更されるループで同じポインターを再利用し、その後strdup()を呼び出すたびにリークを防ぎます。

私はおそらくstring=redup(&string、 "new contents")..のようにそれを実装するでしょうが、それは私だけです。

編集

これが私の「redup」関数の一部です。これは、あなたが投稿したものと似たようなことを、まったく異なる方法で実行している可能性があります。

int redup(char **s1, const char *s2)
{
    size_t len, size;

    if (s2 == NULL)
        return -1;

    len = strlen(s2);
    size = len + 1;

    *s1 = realloc(*s1, size);

    if (*s1 == NULL)
        return -1;

    memset(*s1, 0, size);
    memcpy(*s1, s2, len);

    return len;
}

もちろん、おそらく* s1のコピーを保存し、realloc()が失敗した場合はそれを復元する必要がありますが、そのパラノイドを取得する必要はありませんでした。

于 2009-03-09T04:35:16.027 に答える
0

newstrdup() 関数のプロトタイプはライブラリの strdup() バージョンと同じように見えるため、コード内の「string」変数で何が起こっているかを確認する必要があると思います。

コードに free(*string) 呼び出しはありますか?

複製された文字列のコピーを内部的に保持し、同じ文字列へのポインターを再度返す場合を除き、これは奇妙なことのように見えます。

繰り返しますが、なぜですか?

于 2009-03-09T04:57:50.557 に答える