【问题标题】:Dynamic Memory Allocation inside Class类内的动态内存分配
【发布时间】:2016-09-13 09:39:40
【问题描述】:

如何在类中动态分配内存?

为了澄清我的问题,我做了一个例子。我会构造一个 A 的实例 a 并将其复制到 b 中。使用后,a 和 b 将被破坏,分配的内存将在析构函数中释放两次。

那么我该如何处理这种情况呢?

#include <stdlib.h>

class A {
public:
    char * allocatedMemory;
    A(int length) {
        allocatedMemory = (char *) malloc(sizeof(char) * length);
    }

    ~A(){
        free(allocatedMemory);
    }
};

int main() {
    A a = A(50);
    A b = a;
    return 0;
}

PS:要了解上下文:我试图通过示例弄清楚 std::string 如何分配和释放内存。当然只有基本配置。

【问题讨论】:

  • 搜索“三的规则”(以及“五”和“零”)。
  • 你考虑过重载赋值运算符吗?
  • 嗨,您面临的问题是由于浅拷贝。如果您不显式提供复制构造函数,则编译器将提供默认复制构造函数以使用现有对象初始化一个对象。默认复制构造函数执行按位复制。 IE。只需将存储在一个对象指针中的地址复制到另一个对象。为了避免这种双重释放问题,你需要做深拷贝。编写您自己的复制构造函数,在该复制构造函数中使用 new 为您的字符指针显式分配内存,然后使用 memcpy() 复制实际内容。希望这会有所帮助。
  • 谢谢大家。我只需要复制构造函数!
  • 为什么不直接使用已经有你想要的语义的东西,比如std::vector&lt;char&gt;?

标签: c++ memory memory-management dynamic-memory-allocation


【解决方案1】:

您好,您遇到的问题是浅拷贝。如果您不显式提供复制构造函数,则编译器将提供默认复制构造函数以使用现有对象初始化一个对象。默认复制构造函数执行按位复制。 IE。只需将存储在一个对象指针中的地址复制到另一个对象。为了避免这种双重释放问题,你需要做深拷贝。编写您自己的复制构造函数,在该复制构造函数中使用 new 为您的字符指针显式分配内存,然后使用 memcpy() 复制实际内容。希望这会有所帮助。

 #include <stdlib.h>
 class A 
 {
    public:
    char * allocatedMemory;
    int length;
    A(int length):length(length) 
    {
          // i am ignoring exception due to failure in new to keep code simple
          this->allocatedMemory = new char[length];
    }
    A(const A& obj)
    {
        this->allocatedMemory = new char[obj.length];
        memcpy(this->allocatedMemory, obj.allocatedMemory, obj.length);
        this->length = obj.length;

    }
    A& operator=(const A& obj)
    {
         if(this != &obj)
         {
             if(this->length == obj.length)
             {
                 memcpy(this->allocatedMemory, obj.memory, obj.length);
             }
             else
             {
                 delete[] this->allocatedMemory;
                 this->allocatedMemory = NULL;
                 this->allocatedMemory = new char[obj.length];
                 memcpy(this->alocatedMemory, obj.allocatedMemory, obj.length);
                 this->length = obj.length;
             }
        }
        return *this;
     }


    ~A()
   {
        if(allocatedMemory)
            delete[] allocatedMemory;
   }
};

int main() 
{
    A a = A(50);
    A b = a;
    return 0;
}

【讨论】:

  • memcpy 需要一个长度参数,而operator= 有很多错误。对于开始,我建议对operator= 使用复制和交换。
  • if(allocatedMemory) 是多余的,delete 是一个空指针是安全的。此外,您正在正确处理构造函数中的分配失败 - 构造函数在无法创建对象时抛出是一种很好的做法
  • @M.M 嗨,感谢您的评论。请让我知道 operator= 这里的错误是什么。我会改进这些错误。
  • 重新开始,想想你在做什么。您忘记在当前对象中设置长度和分配的 sinze。见what is the copy and swap algorithm
  • obj.length &gt; length的情况你还是没处理好
猜你喜欢
  • 2016-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-13
  • 1970-01-01
  • 2021-02-15
  • 2013-07-01
相关资源
最近更新 更多