【问题标题】:correct algo for deep copying a string in c++ [closed]在 C++ 中深度复制字符串的正确算法 [关闭]
【发布时间】:2022-01-15 00:43:48
【问题描述】:

这是我在复制构造函数中深度复制字符串的代码 那么逻辑是否正确??我认为可能存在内存泄漏,我正在尝试修复该问题。m.pStatus 已初始化

class Monkey
{
public:

// insert your code here
Monkey();
Monkey(const Monkey& m);
Monkey& operator=(const Monkey& m);
~Monkey();
// accessors
int getX();
int getY();
char *getStatus();
void deepCopy(const Monkey& m);
// global variables (incremented each creation or destruction)
static int numStringsCreated;
static int numStringsDestroyed;

private:
        // Do not change this data
    int x;
    int y;
    char *pStatus;

};
void Monkey::deepCopy(const Monkey& m)
{
    
    if (m.pStatus)
    {
        // allocate memory for our copy
        pStatus= new char[sizeof(m.pStatus)];
 
        for (int i{ 0 }; i < sizeof(m.pStatus); ++i)
            pStatus[i] = m.pStatus[i];
    }
    else
        pStatus = nullptr;
}


    Monkey::Monkey(const Monkey& m)
    {
        deepCopy(m);
        numStringsCreated++;
    }

【问题讨论】:

  • sizeof(m.pStatus) 很可能是错误的,但如果没有看到定义,我们只能猜测。你可能想要strlen。考虑minimal reproducible example。如果pStatus 指向之前分配的内存,那么这也是内存泄漏。
  • 如果 pStatus 是指针 sizeof(pStatus) 是错误的。它返回指针本身的字节数,对于 32 位代码可能为 4,对于 64 位代码可能为 8。您可能想使用 strlen()
  • 你为什么不使用std::string
  • new char[] 不是字符串,而是字符数组。如果您要在C++ 中编码,请使用提供给您的工具,而不是旧的C 东西。否则,你就是那种被称为C+ 开发人员的奇怪品种:-)
  • @paxdiablo 是更好,更差,还是和三星级程序员一样?

标签: c++ constructor deep-copy


【解决方案1】:

避免使用sizeof(pStatus)。除非变量是固定大小的数组,否则它将计算指针的大小,而不是字符串的长度。

strlenstrcpy 用于经典 C 字符串长度和复制操作。

这更接近你想要的。它确保它清除任何先前的分配,并通过在删除旧的之前先分配副本来隐式处理进行自分配的情况(例如m.deepCopy(m))。你可以做一个额外的优化说if (m.pStatus == pStatus)并完全跳过复制操作。

我的工作假设 pStatus 被初始化为 null 或在构造函数中有效的东西。

void Monkey::deepCopy(const Monkey& m)
{
    char* psz = nullptr;
    if (m.pStatus)
    {
        size_t len = strlen(m.pStatus);
        psz = new char[len+1]; // +1 for null char
        strcpy(pStatus, m.pStatus);
    }

    delete [] pStatus;
    pStatus = psz;      
}

但是,如果 pStatusstd::string,则您不需要执行任何此类分配操作,并且您可能不需要重载赋值运算符或复制构造函数。

【讨论】:

  • 感谢您的帮助。它为我指明了正确的方向。我的代码是正确的,只是我的编译器不接受 strcpy,所以我使用了 strncpy_s。它还需要一个删除语句,就像你的代码。
  • 您的代码是否正确处理 m.deepCopy(m) ?也就是自我复制。从我上面看到的,它并没有隐式处理。
  • 此外,如果您只是将 pStatus 设置为 std::string 类型,则不需要复制构造函数或重载赋值运算符。您甚至可能也不需要析构函数。这些操作的默认实现是正确的。
  • 谢谢我会做这个补充
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-19
  • 2015-10-21
  • 2013-03-11
  • 1970-01-01
  • 2020-09-02
相关资源
最近更新 更多