如何在c++中释放指向结构的指针数组
How to deallocate array of pointers to structures in C++?
我创建了一个类,实现了指向结构的指针数组…我知道如何添加记录到这个数组,但我不知道,如何正确地删除它们,因此我有内存泄漏。我的数组的大小在需要时增加,我知道数组的大小以及我在那里有多少条记录。我习惯用有垃圾回收器的语言编码,所以这对我来说很困惑。如果你们中有人能告诉我,如何正确地释放这个数组,我将很高兴。
请注意,我不能使用vector
。我的include限定为:
#include <iostream>
#include <iomanip>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
我的代码:
struct DbRecord
{
string oName;
string oAddr;
string cName;
string cAddr;
};
class CCompanyIndex
{
public: CCompanyIndex(void);~CCompanyIndex(void);
bool Add(const string & oName,
const string & oAddr,
const string & cName,
const string & cAddr);
bool Del(const string & oName,
const string & oAddr);
bool Search(const string & oName,
const string & oAddr,
string & cName,
string & cAddr) const;
int size;
int position;
DbRecord * * db;
};
CCompanyIndex::CCompanyIndex(void)
{
db = new DbRecord * [1000];
size = 1000;
position = 0;
}
CCompanyIndex::~CCompanyIndex(void)
{
}
int main(int argc, char const * argv[])
{
CCompanyIndex c1;
// do something..with c1, i.e. add there some records to array
// ...
// ...
// delete it now
}
经验法则是在析构函数中反转构造函数中与内存管理相关的操作。也就是说,既然在构造函数中有db = new DbRecord * [1000];
,那么在析构函数中也应该有delete[] db;
。
请注意,这里很可能不需要动态内存管理(使用按值语义),您可能希望查看c++提供的更高级的抽象,例如由AndyProwl和JamesKanze建议的vector
类。
使用std::vector
来避免必须通过原始指针、new[]
和delete[]
手动管理内存。这样做(正如您所经历的)容易出错,并且很容易导致内存泄漏或未定义行为。
DbRecord
对象的引用。您应该根据所需的所有权策略选择智能指针。在这里,我假设std::shared_ptr
是合适的。但是,请注意,如果不需要引用语义,则根本不应该使用指针,而应该将容器声明为std::vector<DbRecord>
。这里我假设您确实需要引用语义,因为您的原始版本使用(原始)指针;但是,如果不需要,请不要使用指针。
因此给定必要的#include
指令和using
声明:
#include <string>
#include <vector>
#include <memory>
using std::string;
using std::vector;
using std::shared_ptr;
和(未改变的)DbRecord
数据结构的定义:
struct DbRecord {
string oName;
string oAddr;
string cName;
string cAddr;
};
您可以这样更改CCompanyIndex
的定义(如您所见,用户定义的默认构造函数和析构函数现在是多余的,您可以让编译器隐式地生成它们):
class CCompanyIndex {
public:
// No more need for a user-defined default constructor and destructor!
bool Add(const string & oName,
const string & oAddr,
const string & cName,
const string & cAddr);
bool Del(const string & oName,
const string & oAddr);
bool Search(const string & oName,
const string & oAddr,
string & cName,
string & cAddr) const;
std::vector<std::shared_ptr<DbRecord>> db;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
};
最后,注意您不需要执行任何手动清理:
int main(int argc, char const *argv[])
{
CCompanyIndex c1;
// do something..with c1, i.e. add there some records to array
// ...
// ...
// NO NEED TO MANUALLY DELETE IT NOW!
}
您不应该在这里进行任何内存管理。有几乎没有任何理由使用array new;只使用std::vector
。真的没有理由动态地分配DbRecord
;因为它具有值语义:
std::vector<DbRecord> db;
很好地完成了这项工作。
您可以使用delete
和delete[]
操作符来释放内存。例如,可以像下面这样释放析构函数中的内存:
CCompanyIndex::~CCompanyIndex(void)
{
// delete objects pointed-to in a loop.
// !! the objects MUST have been allocated, or the pointers MUST be set to null.
// note that 'delete' is null-safe.
for(DbRecord* it=db; it<db+position; ++it)
{
delete *it;
}
// delete the array of pointers
delete[] db;
}
delete
释放为单个对象分配的内存(通过new
),而delete[]
释放为对象数组分配的内存(通过new[]
,如您的情况)。
但是不要重新发明轮子-只使用std::vector<DbRecord*>
。它为您做内存管理,您的代码将更简单,更易读。c++提供了强大的标准库,因此大多数程序员甚至不需要使用手动内存管理。
- 如何在 C# 中映射双 C 结构指针?
- C++:映射结构中的结构指针
- C++:添加新结构时,结构指针向量中的所有元素都会更新
- 类的静态结构指针声明在C++
- 在两个.cpp文件之间定义全局类/结构指针
- 返回对常量结构(指针类型)成员的引用:明显的左值到右值转换
- 是否可以将无符号字符数组reinterpret_cast到仅包含C++中无符号字符成员的结构指针
- 如何在地图中使用结构指针
- 结构指针在"新"调用上给出已分配的地址?
- 铸造结构指针指向C 的工会指针
- c++ 结构指针在初始化为 NULL 时无法读取内存
- 函数中的结构指针的地址为0x1
- C 用结构指针初始化结构
- C 结构指针铸成数组Interop C#
- 方法中不允许访问结构指针
- 如何打印出结构指针
- MPI_Op_create:候选功能不可行.自定义结构指针不能解释为空指针
- 尝试将结构指针传递给类时出错
- 初始化结构指针的值
- 使用 pybind11 将自定义结构(指针向量)从 C++ 传递到 python 的方法是什么?