2012-12-24 68 views
60

我讀到strcpy是用於複製一個字符串,strdup返回一個指向新字符串的指針來複制該字符串。strcpy vs strdup

您能解釋一下您喜歡使用哪種情況strcpy以及您喜歡使用哪種情況strdup

回答

90

strcpy(ptr2, ptr1)相當於while(*ptr2++ = *ptr1++)

這裏爲的strdup相當於

ptr2 = malloc(strlen(ptr1)+1); 
strcpy(ptr2,ptr1); 

memcpy version可能更有效)

所以,如果你想你已經複製到被使用的字符串在另一個函數中(因爲它是在堆段中創建的)可以使用strdup,否則strcpy就足夠了。

+1

除了最後一句話之外的好答案,這是令人困惑的。我想你的意思是'strdup()'ed字符串的生命週期可以擴展到當前函數的末尾,但無論如何,情況可能如此(如果'strcpy()'的目標是調用者提供的緩衝區,全局變量,或者使用'malloc()'或'new'手動分配)。 –

+1

是的確如果調用者提供的緩衝區本身是全局變量或動態指針,那麼不需要使用strdup我剛剛指出了其中一個用例場景,並感謝您完成它。 –

+5

真的很喜歡'while(* ptr2 ++ = * ptr1 ++)'! :) – Aloys

12

strdup分配用於在堆上新的字符串存儲器,同時使用strcpy(或它的更安全strncpy變體光盤)我可以堆或堆複製字符串到預分配的內存。

+1

爲什麼強調 「不是」?是不是可以使用'strcpy'來複制到靜態緩衝區? –

+0

我試圖強調這兩個函數之間的使用差異,而沒有將太多內存管理問題混淆在答案上。但是,對於靜態緩衝區,您是正確的。 – Oren

+0

如果你不想混亂,你可以在「預先分配的內存」後結束答案:-) –

38

函數strcpystrncpy是C標準庫的一部分,可在現有內存上運行。也就是必須提供內存中的函數拷貝字符串數據,並且作爲推論,你必須有你自己的方法來找出你需要多少內存。

通過對比,strdup是一個Posix函數,它爲您執行動態內存分配。它返回一個指向新分配的內存的指針,它已經複製了該字符串。但現在負責這個內存,最終必須free它。

這使得strdup「隱藏malloc」便利功能之一,這也可能是爲什麼它不是標準庫的一部分。只要您使用標準庫,就知道您必須每調用一個freemalloc/calloc。但是如strdup等函數引入了一個隱藏的malloc,爲了內存管理的目的,您必須將它與malloc相同。 (另一個這樣的隱藏分配函數是GCC的abi::__cxa_demangle()。)注意!

0

char *strdup(char *pszSrch);

strdup將分配存儲的原始字符串的大小。如果存儲分配成功,則將原始字符串複製到重複字符串。

strdup d返回NULL失敗。如果未分配內存,則複製失敗strdup返回NULL

6

accepted answerstrdup實施呈現爲:

ptr2 = malloc(strlen(ptr1)+1); 
strcpy(ptr2,ptr1); 

然而,有些次優的,因爲這兩個strlenstrcpy需要通過檢查每個字符是要查找的字符串的長度一個\0

使用memcpy應該更高效:

char *strdup(const char *src) { 
    size_t len = strlen(src) + 1; 
    char *s = malloc(len); 
    if (s == NULL) 
     return NULL; 
    return (char *)memcpy(s, src, len); 
} 
+0

很好的答案,以有效的方式將'strcpy'的概念性用法實現爲'strdup'。 –