在MSVC中,_strdup(const char *p)函數的作用是返回一個指針,這個指針指向p的一個復制串。
#include<iostream> int main() { char str[]="this is a string"; char *dstring=strdup(str); std::cout<<dstring; std::cout<<(int)str<<" "<<(int)dstring<<std::endl; return 0; }
結果輸出 :this is a string2488768 6066056。這是兩個不同的地址,代表了調用strdup函數,返回的是一個復制串。但是,請注意進一步的分析。
同時,編譯器還會提示:
warning C4996: 'strdup': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _strdup.
這不是不是標准C的東西,要想避免warning,改用_strdup()。
這是_strdup()的源代碼,可以看出參數一定不能為NULL,因為包含了strlen()
char * __strdup(const char *s) { size_t len = strlen(s) +1; void *new = malloc(len); if (new == NULL) return NULL; return (char *)memecpy(new,s,len); }
在MSVC的幫助文檔可以找到提示,調用strdup后一定要free()釋放內存,不然會內存泄漏。
但是,看下面的代碼:
#include<iostream> int main() { char str[]="this is a string"; char *dstring=_strdup(str); delete str; std::cout<<dstring; std::cout<<(int)str<<" "<<(int)dstring<<std::endl; return 0; }
dstring復制str中的字符串后,刪除str內容,再輸出dstring。結果是:段錯誤!
而刪除dstring,對str將沒有任何影響。
請注意,上面的代碼中都沒有包含<string.h>,在VS2010中依然能夠運行,答案還未找到。
在linux中,則必須#include<string.h>,並且,不能用#include<string>代替,不然會提示找不到strdup,加上std::strdup也沒用(其實,這不是標准庫的東西,加上std是錯上加錯。。。)
同時,g++編譯,也不能使用_strdup代替strdup,因為_strdup是MSVC的東西。
對於,<string.h>和<string>,它們決不能等同。
string中的命名空間是std,而string.h中的函數是全局的函數。