字符串复制函数-strdup

字符串复制函数-strdup

strdupC/C++语言中一个非常实用的字符串操作函数,它的名字来源于 “string duplicate”(字符串复制)。

其核心作用是:自动在堆(Heap)上分配一块新的内存,将给定的源字符串完整地复制过去,并返回这块新内存的指针。

1. 函数原型与头文件

它通常声明在<string.h>头文件中:

#include<string.h>char*strdup(constchar*s);

如果指定C++中的std::string,需要引入头文件<string>

如果指的是C语言的字符串处理函数,如strdupstrcpy等,不需要引入头文件<string>,而是需要引入C语言的头文件<cstring><string.h>

C++中推荐用<cstring>代替<string.h>

2. 工作原理

你可以把strdup看作是一个“智能字符串复印机”。它在底层等价于以下操作:

  1. 计算源字符串的长度(strlen(s) + 1,包含结尾的\0)。
  2. 调用malloc动态分配相应大小的内存。
  3. 将源字符串的内容拷贝到新分配的内存中。
  4. 返回新内存的地址。

3. 返回值

  • 成功:返回指向新分配且已复制字符串的指针。
  • 失败:如果系统内存不足导致分配失败,则返回NULL

4. ⚠️ 极其重要的注意事项

  • 必须手动释放内存:因为strdup内部调用了malloc,所以当你不再需要这个复制出来的字符串时,必须调用free()来释放内存,否则会导致内存泄漏。
  • 跨平台差异strdup是 POSIX 标准函数,在 Linux 和 macOS 下可以直接使用。但在 Windows 平台(如使用 Visual Studio)下,它通常被命名为_strdup()
  • 空指针危险:如果传入的源字符串sNULL,会导致未定义行为(通常表现为程序崩溃),使用前需确保参数有效。

5. 使用示例

#include<stdio.h>#include<string.h>#include<stdlib.h>intmain(){constchar*original="Hello, World!";// 复制字符串char*copy=strdup(original);// 检查是否分配成功if(copy==NULL){printf("内存分配失败\n");return1;}printf("原字符串: %s\n",original);printf("复制的字符串: %s\n",copy);// 用完之后务必释放内存!free(copy);return0;}

一道C++例题分享

#include<iostream>#pragmawarning(disable:4996)usingnamespacestd;/* 类定义 */classChoiceQuestion{//“选择题”类// 所有字符串成员都使用 char*指针,并通过strdup()进行深拷贝,需要手动管理内存;char*stem;//题干char*options[4];//对应于下标0、1、2、3 的 A、B、C、D 4个备选答案charcorrect_option;//正确答案('A'、'B'、'C' 或 'D')public:ChoiceQuestion(//构造函数constchar*the_stem,constchar*optionA,constchar*optionB,constchar*optionC,constchar*optionD,charcorrect);// ERROR **********found**********ChoiceQuestion(ChoiceQuestion&cq);//复制构造函数~ChoiceQuestion();//析构函数voidshow()const;//显示对象内容};ChoiceQuestion::ChoiceQuestion(constchar*the_stem,constchar*optionA,constchar*optionB,constchar*optionC,constchar*optionD,charcorrect){stem=strdup(the_stem);options[0]=strdup(optionA);options[1]=strdup(optionB);options[2]=strdup(optionC);options[3]=strdup(optionD);// ERROR **********found**********correct_option=correct;}// 复制构造函数ChoiceQuestion::ChoiceQuestion(ChoiceQuestion&cq){stem=strdup(cq.stem);for(inti=0;i<4;i++)// ERROR **********found**********// 每个选项单独拷贝options[i]=strdup(cq.options[i]);correct_option=cq.correct_option;}// 析构函数ChoiceQuestion::~ChoiceQuestion(){delete[]stem;for(inti=0;i<4;i++)delete[]options[i];}voidChoiceQuestion::show()const{cout<<endl<<stem;for(inti=0;i<4;i++)cout<<endl<<" "<<char(i+'A')<<") "<<options[i];cout<<endl<<"正确答案:"<<correct_option<<endl;}intmain(){ChoiceQuestionq1("冬天,池塘已经结冰,一头口渴的牛正在冰面上打洞,以便喝到池塘中的水。这头牛所采用的打洞方法是","用头撞击冰面;","用舌头舔冰面;","用臀部猛坐冰面;","用蹄子敲击冰面。",'B');ChoiceQuestionq2("冬天,池塘已经结冰,一匹口渴的马正在冰面上打洞,以便喝到池塘中的水。这匹马所采用的打洞方法是","用头撞击冰面;","用舌头舔冰面;","用臀部猛坐冰面;","用蹄子敲击冰面。",'D');q1.show();q2.show();return0;}

运行结果

冬天,池塘已经结冰,一头口渴的牛正在冰面上打洞,以便喝到池塘中的水。这头牛所采用的打洞方法是 A) 用头撞击冰面; B) 用舌头舔冰面; C) 用臀部猛坐冰面; D) 用蹄子敲击冰面。 正确答案:B 冬天,池塘已经结冰,一匹口渴的马正在冰面上打洞,以便喝到池塘中的水。这匹马所采用的打洞方法是 A) 用头撞击冰面; B) 用舌头舔冰面; C) 用臀部猛坐冰面; D) 用蹄子敲击冰面。 正确答案:D