2016-07-07 5 views
0

バッファ間で文字列を動かすとき、私はしばしばchar*をデータバッファとして扱い、文字列バッファ(strncpystrncatなど)のどれも使用しません。 例:memcpyをstrncpyなどに使うのは悪い習慣ですか?

memcpy(target, src, strlen(src) + 1) // after buffer size checks 
//vs 
strncpy(target, src, target_size - 1); 
target[target_size - 1] = 0; 

これは悪い習慣ですか?

編集:私は違いを知っています、これは重複ではなくむしろ標準的な練習の問題です。一度strlenで、一度memcpyに -

memcpy(target, src, strlen(src) + 1) // after buffer size checks 

+0

'target'サイズが少なくともstrlen(src)+ 1バイト長であることを許可すると仮定すると、それを行うことに害はありません。 – pah

+1

文字列の長さを知っていれば、 'memmove()'や 'memcpy()'が良い方法です。文字列の長さがわからない場合、 'str *()'ルーチンは災害になることが多く、 'strncat()'は 'strncpy()'よりも悪いですが、大きなマージンではありません。 –

+0

'memcpy()'は 'strlen(src)+ 1'文字を書き込みます。 'strncpy(target、src、target_size - 1); target [target_size - 1] = 0; 'は' target_size'文字を書き込みます。重要な文字列の長さは '' abc ''のコピーの1024バッファのように大きくなければなりません。 – chux

答えて

1

意味とサイズがわかっている場合は問題ありません。 strncpyは最初のnullで停止し、文字列が短い場合はnバイトまでのnバイトまでの宛先にも次のバイトを埋め込むことに注意してください(ソースに1つもない場合はnullバイトを書きません)。 strncpyは、void *ではなく、すべての場合にchar *と予想されるので、より良い型チェッキングを提供します。

どれが効率的かは議論の余地がありますが、1命令でメモリブロック全体をコピーできるCPUバルク命令に基づいて、strncpyはコピーされた各バイトをNUL文字でチェックするため、memcpyがおそらく高速でしょう。

+1

"strncpyは最初のヌルで停止します" - > no。それ以上のことをします。ターゲットベースをサイズ0で埋めます。 – chux

+0

あなたが正しいです: 'srcの長さがnより小さい場合、strncpy()は合計nバイトが書き込まれるようにdestに追加のnullバイトを書き込みます。' – Taywee

+0

'memcpy()'は、 'strncpy()'のように、文字列の長さまでしか宛先バッファのサイズを書く必要はありません。小さな文字列/バッファを扱う人は大丈夫ですが、大きなバッファとさまざまな長さの文字列を使用すると、節約が重要になります。 – chux

3

使用すると、潜在的に二回、文字列を横断含まれます。 strcpyを使用した場合、パフォーマンスの低下はわずかです。

関連性のない理由で文字列の長さを計算したり、他のリソースからの文字列の長さがある場合は、memcpystrncpyより優れているか悪いかは不明です。あなたは計算にいない他の理由のための文字列の長さをするか、または他のリソースからの文字列の長さを持っていない場合

は、strcpyの代わりに、memcpyまたはstrncpyを使用することをお勧めします。

+0

OPは 'strncpy()'の比較について尋ねました。 – chux

+0

非常に確かに、大きな文字列を使って作業していますが、私はすでに長さが分かっていることを感謝しています。 – JavaProphet

+0

バッファオーバーラン攻撃の影響を受けやすいので、私は個人的には 'strcpy'を推奨しません。 – Taywee

関連する問題