You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 15:24:03