[解決済み】 strdup() - Cでは何をするのですか?
質問
の目的は何ですか?
strdup()
という関数があります。
どのように解決するのですか?
CとUNIXが単語を割り当てる省略方法に慣れていると仮定すれば、まさにその通りです、それは 文字列の重複 :-)
実はISO C規格の一部ではないことに留意してください。 (a) (POSIXのものです)、事実上、以下のコードと同じことを行っています。
char *strdup(const char *src) {
char *dst = malloc(strlen (src) + 1); // Space for length plus nul
if (dst == NULL) return NULL; // No memory
strcpy(dst, src); // Copy the characters
return dst; // Return the new string
}
言い換えれば
-
古い文字列を格納するのに十分なメモリを確保しようとします(さらに、文字列の終わりを示す '∕0' 文字を追加します)。
-
割り当てに失敗した場合は
errno
からENOMEM
を返しNULL
をすぐに実行します。の設定errno
からENOMEM
は何かmalloc
はPOSIXで行われていることなので、明示的にstrdup
. もし、あなたが ではなく POSIX準拠の場合、ISO Cは実際にはENOMEM
ということで、ここには入れていません。 (b) . -
そうでなければ、アロケーションがうまくいったので、古い文字列を新しい文字列にコピーします。 (c) そして新しいアドレスを返します (呼び出し元はある時点でこれを解放する責任があります)。
これは概念的な定義であることに留意してください。ライブラリ作者であれば、使用するプロセッサに合わせて最適化されたコードを提供できるはずです。
(a)
ただし
str
と小文字は、将来の方向性のために規格で予約されています。から
C11 7.1.3 Reserved identifiers
:
各ヘッダーは、関連するサブセクションにリストされたすべての識別子を宣言または定義し、*オプションで、関連する将来のライブラリ方向サブセクションにリストされた識別子を宣言または定義します**。
の今後の方向性は
string.h
には
C11 7.31.13 String handling <string.h>
:
で始まる関数名
str
,mem
またはwcs
の宣言に小文字を加えてもよい。<string.h>
ヘッダを作成します。
だから、安全を期すなら別の呼び方をしたほうがいい。
(b)
この変更は、基本的には、次のように置き換えることになります。
if (d == NULL) return NULL;
を使っています。
if (d == NULL) {
errno = ENOMEM;
return NULL;
}
(c)
なお、私は
strcpy
というのは、その意図を明確に示しているからです。実装によっては、(すでに長さがわかっているため)より早く
memcpy
なぜなら、より大きなチャンクで転送したり、並列に転送したりすることができるからです。あるいは、そうでない場合もあります :-) 最適化のマントラその1:「測って、当てずっぽうにしない」。
いずれにせよ、その道を歩むことになった場合、次のようなことをすることになります。
char *strdup(const char *src) {
size_t len = strlen(src) + 1; // String plus '\0'
char *dst = malloc(len); // Allocate space
if (dst == NULL) return NULL; // No memory
memcpy (dst, src, len); // Copy the block
return dst; // Return the new string
}
関連
-
[解決済み】式は、単純なポインタ演算を使用して完全なオブジェクト型へのポインタでなければなりません【重複】。
-
[解決済み】Cygwin - Makefile-error: ターゲット `main.o' のレシピに失敗しました。
-
[解決済み】LinuxのI_PUSHに相当するもの
-
[解決済み] callとapplyの違いは何ですか?
-
[解決済み] C言語では「?」演算子は何をするのですか?
-
[解決済み] JavaScriptの変数のスコープとは何ですか?
-
[解決済み] C言語における「static」の意味とは?
-
[解決済み】C/C++の"-->"演算子とは何ですか?
-
[解決済み】JavaScriptの関数にデフォルトのパラメータ値を設定する
-
[解決済み】関数の前のエクスクラメーションマークは何をするのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】変数の警告が設定されているが使用されていない
-
[解決済み】 `S_ISREG()` とは何ですか、そして何をするのですか?
-
[解決済み] strtokのセグメンテーションフォールト
-
[解決済み】 strcpyとstrdupの比較
-
[解決済み】警告。この関数ではXが初期化されていない状態で使用される可能性があります。
-
[解決済み】EAGAINとはどういう意味ですか?
-
[解決済み】コンパイラの警告 - 真理値として使用される代入の周囲に括弧を付けることを推奨する
-
[解決済み】Linuxソケットのwrite()でBad File Descriptorが発生するC
-
[解決済み] strcpy'で作成した文字列は解放する必要がありますか?
-
[解決済み] ある構造体を別の構造体にコピーする