如何实现CopyCat类构造函数对argc、argv、environ的深拷贝
CopyCat 类实现方案
补全后的公开头文件(copycat.h)
#ifndef INCLUDED_COPYCAT_ #define INCLUDED_COPYCAT_ #include <cstddef> class CopyCat { size_t d_size; char **d_data; public: CopyCat(); // 拷贝全局environ CopyCat(int argc, char **argv); CopyCat(char **data); // 拷贝任意类environ格式的变量 ~CopyCat(); // 析构函数释放深拷贝资源 // 可选:补充拷贝控制成员,避免浅拷贝导致的double free问题 CopyCat(CopyCat const &other) = delete; CopyCat &operator=(CopyCat const &other) = delete; private: // 私有辅助函数:统一处理null结尾的char**数组的深拷贝逻辑 void copyNullTerminatedArray(char **source); // 私有辅助函数:拷贝指定长度的char**数组 void copySizedArray(char **source, size_t count); }; #endif
内部实现逻辑(copycat.cpp)
首先引入依赖头文件,声明全局environ变量:
#include "copycat.h" #include <cstring> // 声明全局环境变量指针,部分系统可替换为引入<unistd.h> extern char **environ;
私有辅助函数实现
两个辅助函数复用深拷贝逻辑,避免不同构造函数重复编写相同代码:
void CopyCat::copyNullTerminatedArray(char **source) { // 先计算源数组长度(遍历到末尾nullptr为止) d_size = 0; while (source[d_size]) { d_size++; } // 分配指针数组空间,多留一位存末尾nullptr d_data = new char*[d_size + 1]; // 逐个拷贝每个字符串 for (size_t i = 0; i < d_size; i++) { size_t strLen = strlen(source[i]) + 1; d_data[i] = new char[strLen]; memcpy(d_data[i], source[i], strLen); } // 末尾补nullptr,保持和源数组相同的遍历特性 d_data[d_size] = nullptr; } void CopyCat::copySizedArray(char **source, size_t count) { d_size = count; d_data = new char*[d_size + 1]; for (size_t i = 0; i < d_size; i++) { size_t strLen = strlen(source[i]) + 1; d_data[i] = new char[strLen]; memcpy(d_data[i], source[i], strLen); } d_data[d_size] = nullptr; }
构造函数实现
// 无参构造:拷贝全局environ CopyCat::CopyCat() { copyNullTerminatedArray(environ); } // 拷贝指定长度的argv数组 CopyCat::CopyCat(int argc, char **argv) { copySizedArray(argv, static_cast<size_t>(argc)); } // 拷贝任意类environ格式的null结尾数组 CopyCat::CopyCat(char **data) { copyNullTerminatedArray(data); }
析构函数实现
按分配顺序反向释放资源,避免内存泄漏:
CopyCat::~CopyCat() { // 先释放每个字符串资源 for (size_t i = 0; i < d_size; i++) { delete[] d_data[i]; } // 再释放指针数组本身 delete[] d_data; }
核心逻辑说明
- 所有构造函数最终都调用私有辅助函数完成深拷贝,保证指针数组和每个字符串元素都属于当前对象独立所有,修改拷贝后的内容不会影响源数据
- 所有拷贝后的数组末尾都保留了nullptr标记,兼容原生argv、environ的遍历习惯
- 显式删除了拷贝构造和拷贝赋值运算符,避免默认浅拷贝导致的double free问题,如果需要支持拷贝语义可以自行实现对应的深拷贝逻辑
内容的提问来源于stack exchange,提问作者Sergi
相关产品推荐
相关产品推荐

