2016-07-07 47 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; 

這是不好的做法?

編輯:我知道不同,這不是重複的,而是一個標準實踐的問題。

+0

假設您授予'target'大小至少爲strlen(src)+ 1個字節長,這樣做沒有任何壞處。 – pah

+1

如果你知道字符串的長度,那麼'memmove()'或'memcpy()'是很好的習慣 - 雖然不是它可以/應該被經常使用。如果你不知道字符串的長度,那麼'str *()'例程通常是一場災難,'strncat()'比它更糟糕,但不會有太大的差距。 –

+0

'memcpy()'會寫入'strlen(src)+ 1'字符。 'strncpy(target,src,target_size - 1); target [target_size - 1] = 0;'將寫入'target_size'字符。重要的是字符串的長度應該像1024緩衝區的「abc」副本一樣大。 – chux

回答

1

如果你知道語義和大小,這不是一個問題。請記住,如果字符串較短(如果源中沒有一個,則不會寫入空字節),strncpy將停止在第一個空值處,並在目標中填充以下字節,最多爲空字節的n個字符。 strncpy也可以給你一些更好的類型檢查,因爲它在所有情況下預計爲char *,而不是void *

哪一個更有效率值得討論,但是根據可以在一條指令中複製整個內存塊的CPU批量指令,memcpy可能更快,因爲strncpy會檢查每個複製字節的NUL字符。

+1

「strncpy將停在第一個空值處」 - > no。它不止於此。它的大小填滿了目標基礎。 – chux

+0

你是對的:'如果src的長度小於n,則strncpy()向dest寫入額外的空字節,以確保總共寫入n個字節。' – Taywee

+0

'memcpy()'可以更快,因爲它不需要像'strncpy()一樣寫目標緩衝區的大小,直到字符串長度。用小字符串/緩衝區關心,但大緩衝區和各種長度的字符串可以節省很多。 – chux

3

使用

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

可能包括遍歷字符串兩次 - 在memcpy一次strlen一次。如果您使用strcpy,那麼您的演奏效果會很差。

如果由於不相關的原因計算字符串的長度或從其他資源獲取字符串的長度,我們不清楚memcpy是否好於或低於strncpy

如果不計算字符串因其他原因的長度或沒有來自其他資源的字符串的長度,它是更好地使用strcpy,而不是memcpystrncpy

+0

OP詢問了一個'strncpy()'比較。 – chux

+0

非常真實,我發現使用大字符串,我已經很好地知道其他地方的長度。 – JavaProphet

+0

我個人不會推薦'strcpy',因爲它可能容易受到緩衝區溢出攻擊。 – Taywee

相關問題