2009-03-09 28 views
1

私はいくつかのライブラリ関数が使用されていて、そのライブラリを持っていない古いプログラムを持っています。char **をchar *またはcharに変換する

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

* string = newstrdup( "Some string goes here");

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

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

+0

newstrdup()関数を貼り付けることはできますか? –

+0

@ tinkertim: "ライブラリ関数を使用していて、ライブラリを持っていない古いプログラムがあります" ... –

+0

newstrdupが使用されている古いコードを貼り付けることはできますか?ループ内で行うのが好ましい。 .hファイルからnewstrdupの宣言がありますか? – jmucchiello

答えて

3

彼らはstrdupの "新しい"バージョンを書いた理由があるに違いありません。だから、違った扱いをするコーナーケースが必要です。たぶんnull文字列のように空の文字列を返します。

litbの回答はstrdupの代わりですが、私は彼らが何をしたのか理由があると思います。

strdupを直接使用する場合は、defineを使用して新しいコードを書き込むのではなく、名前を変更します。

+1

「新しい」strdupと呼ばれているので、mallocの代わりにnew演算子を使用しています(strdupはmallocを使用します)。彼らはまた、移植性の理由から独自のものを持っているかもしれません。私は知らない:) –

+0

strdup()は標準ではないので、単にnewstrdup()と呼ばれるかもしれないが、広く利用されており、明確にしたい。 'strdup-variant-using-new'を示すために 'newstrdup()'を使用することも考えられます。 –

+0

strdup()ビルトイン関数は大丈夫です。しかし、私が使用して関数を呼び出す場合 *応答= newstrdup( "いくつかの文字列")私はセグメンテーションフォールトを取得しています。 彼はこれに理由があり、克服する方法は何でしょうか? – Chaithra

0

newstrdupはおそらく、渡された文字列の複製である新しい文字列を作成しています。それは文字列へのポインタを返します(それ自体が文字の先が分かります)。

+0

奇妙なことに、文字を指すポインタを返すのはなぜですか? –

+0

@Iraimbilanja:それはそうです。 – sfossen

0

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

私はたぶんその文字列= redup(&文字列、 "新しい内容")のように実装するだろう。しかし、それは私だけです。

編集

ここだけの異なる方法で、あなたが投稿したものと同様のものをやっているかもしれない、私の「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()が失敗した場合にそれを復元してください。しかし、そのパラノイドを取得する必要はありませんでした。

4

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

私はそれが 新しい の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番目のバージョンを使用してください。 2番目のバージョンは文字列をdupするためのメモリがない場合はNULLを返すことに注意してください。その場合、最初の例外は例外をスローします。 にNULL引数を渡すと、動作に関する別の注意が必要です。あなたのライブラリーに応じて、許可されているか許可されていない可能性があります。必要に応じて上記の機能に適切なチェックを挿入します。 POSIXシステムで利用可能なstrdupという関数がありますが、NULL引数を使用することも、C++演算子newを使用してメモリを割り当てることもできません。

とにかく、私はnewstrdup関数のGoogle codesearchを見てきましたが、かなりの数が見つかりました。たぶん、あなたのライブラリーは、結果のうちです:

Google CodeSearch, newstrdup

+0

私はこのようなurプログラムを試しました。 このように私はnewstrdupを呼び出しました。 * ersponse = newstrdup(バッファ)ここでbuffer = "chaithra" ですが、実行中にセグメンテーションエラーが発生しています。 – Chaithra

+0

Chaithra、両方のバージョンを試してみましたか? –

+0

litb私は最初のバージョンだけを試みました。今私は他のものを試してみます。 – Chaithra

0

私はあなたがnewstrdup()関数のプロトタイプが同じであるように思われるように、コードの中に「文字列」変数で何が起こっているかを見てする必要があると思いますライブラリのstrdup()バージョンに追加します。

コードに空き(*文字列)呼び出しがありますか?

重複した文字列のコピーを内部的に保持し、同じ文字列にポインタを戻して戻さない限り、変なことになります。

また、私はなぜでしょうか?

+0

ya、私は同じことを考えていました。別の扱いをしている角の場合があります:) – sfossen

1

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

関連する問題