使用删除与智能指针释放内存以及释放内存的正确方法
Freeing memory with delete vs smart pointer and proper way of freeing memory
我正在为大学做一个项目,我试图找出如何正确删除内存,以及我想出的删除方式是否与使用智能指针具有相同的效果。
这是一个 class,它将包含在公司和团队中工作的所有员工,这些员工基本上具有指向某些员工的指针矢量。
class Company
{
private:
std::string companyInfo;
std::vector<Employee * > employees;
std::vector<Team *> teams;
public:
Company();
~Company();
std::string getCompanyInfo() const;
void setCompanyInfo(const std::string & companyInfo);
bool addEmployee(Employee * employee, const std::string & teamName);
bool addTeam(Team * team);
void printTeams() const;
void printEmployees() const;
};
所以我的问题是:这是释放内存的正确方法吗?如果是,它将提供与使用智能指针自动执行该过程相同的结果。
Company::~Company()
{
for (Employee * e : employees) {
delete e;
}
employees.clear();
for (Team * t : teams) {
delete t;
}
teams.clear();
}
如果使用智能指针更好,我应该在我的特定情况下使用唯一指针还是共享指针。我对智能指针很不满意,当范围结束时它们会删除分配的内存,但我真的很困惑什么时候结束。调用company的析构函数会出现这种情况吗?
提前致谢,如果我的问题看起来很愚蠢,我深表歉意。
Is this a proper way of freeing the memory
假设像这样用new
运算符填充容器,
employees.push_back(new Employee());
teams.push_back(new Team());
那么是的,这就是清理这些资源的正确方法。
... and if its is will it provide the same result as using smart pointers to automate the process.
一般来说是的。您可以调整智能指针如何完成删除它管理的资源的工作,但默认行为是适合您的情况的正确行为(调用 delete
)。
should i use unique or shared pointer
首选应该是std::unique_ptr
。它比 std::shared_ptr
更有效,并且对其管理的对象的使用方式有更多限制。但这有局限性,例如无法复制具有 std::unique_ptr
数据成员的 class(例如 Company
)。使用 std::shared_ptr
可以缓解这个问题,但会带来非常不同的语义——复制 Company
对象意味着 共享 团队和员工。这可能不是您想要的。解决此问题的一种方法是使用 std::unique_ptr
,根据所谓的虚拟构造函数 Employee::clone()
和 Team::clone()
成员函数为 Company
实现复制和复制赋值构造函数。
they delete the allocated memory when the scope end but i'm really confused when will end
一个例子:
void someFunction()
{
Company c;
// stuff...
} // the scope ends here, ~Company will be called
如果你不知道自己在做什么,你应该永远不要在你的代码逻辑中写delete
。这是规则。每当您违反此规则时,预计会发生各种问题。换句话说:始终使用 std 容器 + 智能指针。
唯一指针: 指针的简单包装器,当它超出范围时将删除其下的资源。您不能复制唯一指针,因为如果可以的话谁将拥有指针的所有权?谁来删?只有 1 个对象应该能够删除它。
共享指针: 使复制成为可能,但代价是有一个(原子)计数器来计算有多少对象引用同一指针。当计数器归零时,指针下的资源将被删除。
Is this a proper way of freeing the memory
析构函数没问题,假设所有存储的指针都已使用 new 表达式分配,并假设它们仍然有效,即没有悬空。
虽然清除向量是多余的。向量即将被立即销毁,所以它们的元素无论如何都会被清除。
但是,您的 class 很可能坏了。它是可复制的,如果你制作一个副本,并且不从其中一个副本中删除指针,那么这些对象的析构函数将删除相同的指针,这将导致未定义的行为。
您可以解决这个问题,并通过使用智能指针使您的析构函数更简单(您可以简单地使用隐式析构函数)。
should i use unique or shared pointer
是的,你应该。
您的代码展示了唯一所有权 - Company
唯一拥有 Employee
和 Team
- 因此最简单的更改是使用唯一指针。
I have red about smart pointers and that they delete the allocated memory when the scope end but i'm really confused when will end. Is this going to happen when the destructor of company is called?
删除指针的是智能指针的析构函数
当智能指针为局部变量时,在作用域结束时销毁。就像如果你的 Company
是一个局部变量,它在范围结束时被销毁,它的析构函数将是 运行.
当智能指针为成员时,在销毁超对象时销毁。在您的情况下,您将拥有一个智能指针向量,在这种情况下,当向量被销毁时智能指针也被销毁,或者智能指针从向量中删除。
我正在为大学做一个项目,我试图找出如何正确删除内存,以及我想出的删除方式是否与使用智能指针具有相同的效果。
这是一个 class,它将包含在公司和团队中工作的所有员工,这些员工基本上具有指向某些员工的指针矢量。
class Company
{
private:
std::string companyInfo;
std::vector<Employee * > employees;
std::vector<Team *> teams;
public:
Company();
~Company();
std::string getCompanyInfo() const;
void setCompanyInfo(const std::string & companyInfo);
bool addEmployee(Employee * employee, const std::string & teamName);
bool addTeam(Team * team);
void printTeams() const;
void printEmployees() const;
};
所以我的问题是:这是释放内存的正确方法吗?如果是,它将提供与使用智能指针自动执行该过程相同的结果。
Company::~Company()
{
for (Employee * e : employees) {
delete e;
}
employees.clear();
for (Team * t : teams) {
delete t;
}
teams.clear();
}
如果使用智能指针更好,我应该在我的特定情况下使用唯一指针还是共享指针。我对智能指针很不满意,当范围结束时它们会删除分配的内存,但我真的很困惑什么时候结束。调用company的析构函数会出现这种情况吗?
提前致谢,如果我的问题看起来很愚蠢,我深表歉意。
Is this a proper way of freeing the memory
假设像这样用new
运算符填充容器,
employees.push_back(new Employee());
teams.push_back(new Team());
那么是的,这就是清理这些资源的正确方法。
... and if its is will it provide the same result as using smart pointers to automate the process.
一般来说是的。您可以调整智能指针如何完成删除它管理的资源的工作,但默认行为是适合您的情况的正确行为(调用 delete
)。
should i use unique or shared pointer
首选应该是std::unique_ptr
。它比 std::shared_ptr
更有效,并且对其管理的对象的使用方式有更多限制。但这有局限性,例如无法复制具有 std::unique_ptr
数据成员的 class(例如 Company
)。使用 std::shared_ptr
可以缓解这个问题,但会带来非常不同的语义——复制 Company
对象意味着 共享 团队和员工。这可能不是您想要的。解决此问题的一种方法是使用 std::unique_ptr
,根据所谓的虚拟构造函数 Employee::clone()
和 Team::clone()
成员函数为 Company
实现复制和复制赋值构造函数。
they delete the allocated memory when the scope end but i'm really confused when will end
一个例子:
void someFunction()
{
Company c;
// stuff...
} // the scope ends here, ~Company will be called
如果你不知道自己在做什么,你应该永远不要在你的代码逻辑中写delete
。这是规则。每当您违反此规则时,预计会发生各种问题。换句话说:始终使用 std 容器 + 智能指针。
唯一指针: 指针的简单包装器,当它超出范围时将删除其下的资源。您不能复制唯一指针,因为如果可以的话谁将拥有指针的所有权?谁来删?只有 1 个对象应该能够删除它。
共享指针: 使复制成为可能,但代价是有一个(原子)计数器来计算有多少对象引用同一指针。当计数器归零时,指针下的资源将被删除。
Is this a proper way of freeing the memory
析构函数没问题,假设所有存储的指针都已使用 new 表达式分配,并假设它们仍然有效,即没有悬空。
虽然清除向量是多余的。向量即将被立即销毁,所以它们的元素无论如何都会被清除。
但是,您的 class 很可能坏了。它是可复制的,如果你制作一个副本,并且不从其中一个副本中删除指针,那么这些对象的析构函数将删除相同的指针,这将导致未定义的行为。
您可以解决这个问题,并通过使用智能指针使您的析构函数更简单(您可以简单地使用隐式析构函数)。
should i use unique or shared pointer
是的,你应该。
您的代码展示了唯一所有权 - Company
唯一拥有 Employee
和 Team
- 因此最简单的更改是使用唯一指针。
I have red about smart pointers and that they delete the allocated memory when the scope end but i'm really confused when will end. Is this going to happen when the destructor of company is called?
删除指针的是智能指针的析构函数
当智能指针为局部变量时,在作用域结束时销毁。就像如果你的 Company
是一个局部变量,它在范围结束时被销毁,它的析构函数将是 运行.
当智能指针为成员时,在销毁超对象时销毁。在您的情况下,您将拥有一个智能指针向量,在这种情况下,当向量被销毁时智能指针也被销毁,或者智能指针从向量中删除。