结构体中指针数组的析构函数
Destructor of arrays of pointers in structures
我有这个结构和动态分配的数组。我不能使用std::vector和std::string,因为这是作业。
struct Moves
{
const char* date;
const char* street;
const char* city;
};
struct Data
{
const char* id;
const char* name;
const char* surname;
int count;
Moves** moves;
};
我有一个类,在那里我创建了一个指针数组结构数据,我动态分配char*日期,街道,城市。
现在,我需要删除这些内存块。嗯,我试过了:(我的类的析构函数)问题是:我应该如何正确释放所有分配的内存?
class Reg
{
private:
Data** arr;
int counter;
public:
Reg(){ arr=new Data*[1000]; }
~Reg();
... other methods
};
Reg::~Reg()
{
for(int i=0;i<counter;i++)
{
for(int c=0;c<arr[i]->count;c++)
{
delete arr[i]->moves;
}
delete arr[i];
}
delete [] arr;
}
下面是一个分配的例子:
arr[counter]=new Data;
arr[counter]->id=new char[12];
arr[counter]->id=id;
arr[counter]->name=new char[strlen(name)+1];
arr[counter]->name=name;
arr[counter]->surname=new char[strlen(surname)+1];
arr[counter]->surname=surname;
arr[counter]->moves=new Moves*[100];
arr[counter]->moves[0]=new TMoves;
arr[counter]->moves[0]->city=new char[strlen(city)+1];
arr[counter]->moves[0]->city=city;
arr[counter]->moves[0]->date=new char[strlen(date)+1];
arr[counter]->moves[0]->date=date;
arr[counter]->moves[0]->street=new char[strlen(street)+1];
arr[counter]->moves[0]->street=street;
与其试图解决这段代码中的每个问题,不如告诉你一个编程课程中从未教过的原则:从小而简单的开始,每次增加一点复杂性,每一步都进行测试,永远不要添加不起作用的代码
看这个:
arr[counter]->moves[0]->city=new char[strlen(city)+1];
arr[counter]->moves[0]->city=city;
即使假设这个Moves已经正确构造,您使用new
分配内存,然后立即放弃它,导致内存泄漏。然后如果 city
(与成员同名的变量,不是一个好主意)是指向堆上的char[]
的指针,并且如果在city
的剩余生命周期中没有做任何不好的事情,并且如果没有其他指向该数组的指针存在(或者至少没有做任何不好的事情)那么这将不会导致未定义的行为。你觉得很幸运吗?
可以这样考虑:
struct Moves
{
private:
const char* city;
public:
Moves()
{
city = NULL;
}
~Moves()
{
if(city)
delete [] city;
}
void setCity(const char ncity[])
{
if(city)
delete [] city;
char *temp = new char[strlen(ncity)+1];
strcpy(temp, ncity);
city = temp;
}
};
...
arr[counter]->moves[0]->setCity(someCity);
请注意,一旦setCity()
工作正常,从外部调用它是干净,安全和简单的。一旦Moves
设置正确,Data
可以以类似的方式重写,然后是Reg
。
一旦你习惯了这种方法,你就可以学会使用std::string
,再也不要乱用char[]
了。
这篇文章很难回答,但这里有一些建议:
- 考虑使用
std::vector
代替数组 - 考虑使用
std::string
代替const char * - 考虑将
struct Moves
和struct Data
成员的销毁纳入这些定义
struct Moves
{
const char* date;
const char* street;
const char* city;
~Moves () {
delete [] date;
...
}
};
这是你的class Reg
使用std::vector
来保存类型为Data *
的对象:
class Reg
{
private:
std::vector<Data*> arr;
int counter; // this can probably be removed
public:
Reg()
:arr(1000, NULL) // initialize arr with 1000 NULL raw pointers
{
}
~Reg();
... other methods
};
好的c++参考是cplusplus.com。
如果你加强你的问题,你会得到一些好的答案(并学到很多c++):-)
这有多好?
struct Moves
{
std::string date;
std::string street;
std::string city;
};
struct Data
{
Data() { moves.reserve(1000); }
std::string id;
std::string name;
std::string surname;
typedef std::unique_ptr<Moves> MovesPtr;
typedef std::vector<MovesPtr> MovesList;
MovesList moves;
};
现在你可以添加新的Moves
,它们将在Data
对象销毁时被释放。
int main()
{
Data d;
d.moves.push_back(Data::MovesPtr(new Moves()));
return 0;
}
STL很好,可以帮助你,你应该使用它
- 如何在析构函数中删除C++中动态分配的数组?
- 为什么数组中对象的析构函数在被另一个对象替换时不被调用?
- C++ 在析构函数调用之前删除的动态成员数组
- 取消分配动态分配的字符数组的析构函数
- 在C++中删除指针数组时析构函数崩溃
- 为什么我不能使用已删除或私有析构函数分配类的数组?
- 如何对动态数组中的某些对象调用析构函数
- 为什么析构函数和复制构造函数使用对象数组显示此行为
- 这是删除析构函数中的数组的正确方法吗?
- 指向数组的指针的析构函数
- 具有受保护析构函数的类数组的动态分配
- 析构函数立即调用并删除我的数组
- 为什么析构函数不释放数组内存?
- 如何在具有指向对象的指针数组的类中创建复制构造函数和析构函数,其中对象本身具有指向整数的指针数组
- 析构函数删除在 main 中声明的动态数组
- 删除类数组而不调用析构函数
- 构造函数、析构函数和指针(以及向量、数组和删除等等)
- C++析构函数删除包含动态数组作为数据成员的对象时的用法
- 为什么不为对象数组调用析构函数
- 指向数组的指针数组的析构函数