C++ 如何正确管理动态分配对象的内存?
我正在建立一个程序来处理一些伪造的图书订单,我想我遇到了如何分配内存的问题 程序流程首先打开一个包含每个客户信息的文本文件。我在循环中标记这些信息,并创建要插入数据库的C++ 如何正确管理动态分配对象的内存?,c++,memory-management,C++,Memory Management,我正在建立一个程序来处理一些伪造的图书订单,我想我遇到了如何分配内存的问题 程序流程首先打开一个包含每个客户信息的文本文件。我在循环中标记这些信息,并创建要插入数据库的Customer对象。以下是我正在使用的循环: while(fgets(stringBuf,100,dbFile)) { string name(strtok(stringBuf,"|")); int custID = atoi(strtok(NULL,"|"));
Customer
对象。以下是我正在使用的循环:
while(fgets(stringBuf,100,dbFile))
{
string name(strtok(stringBuf,"|"));
int custID = atoi(strtok(NULL,"|"));
double credit = atof(strtok(NULL,"|"));
string street(strtok(NULL,"|"));
string state(strtok(NULL,"|"));
string zip(strtok(NULL,"|"));
Customer *newEntry = new Customer(name,custID,credit,street,state,zip);
database.insert(newEntry);
}
我使用数据库
作为存储客户
对象的一种方式,这些对象稍后会在程序中修改。关键是这些Customer
对象将被修改,并将无限期地保留在数据库中,直到程序结束。当我试图清理分配给这些客户的内存时,问题就出现了。我的数据库
设置为已排序的链表,这是我用于从数据库
中删除客户
的功能:
void CustomerList::remove(int ID)
{
Customer *lead = this->getHead();
Customer *tail = NULL;
while(lead->getID() != ID) {
tail = lead;
lead = lead->getNext();
}
if(tail == NULL) { // means that lead is pointing to head
this->setHead(lead->getNext());
lead->setNext(NULL);
delete lead;
return;
}
else if(lead == NULL) { // element not found in the list
cout << "Element to be removed was not found in the list\n";
return;
}
else {
tail->setNext(lead->getNext());
lead->setNext(NULL);
delete lead;
return;
}
void CustomerList::remove(int-ID)
{
客户*lead=this->getHead();
客户*tail=NULL;
while(lead->getID()!=ID){
尾=铅;
lead=lead->getNext();
}
如果(tail==NULL){//表示引线指向头部
此->设置头(lead->getNext());
lead->setNext(空);
删除铅;
回来
}
else如果(lead==NULL){//在列表中找不到元素
cout setNext(lead->getNext());
lead->setNext(空);
删除铅;
回来
}
<>我担心的是,我没有正确删除<代码>客户>代码>对象。我知道在C中,由<代码> MalOC/<代码>创建的精确指针需要返回到<代码>免费< /COD>,但是我不确定C++中是否与“代码>新的< /代码>和<代码>删除>代码>相同。IGIAL循环,但是我尝试用另一个类的方法返回内存。这是一个有效的内存管理方式,还是有更好的方法来做?< /P> < P> C++中的规则有点不同:程序需要调用一个代码:>代码>删除<代码>或<代码>删除[]。
operator,具体取决于用于分配内存的运算符
- 如果使用
为单个对象分配内存,请使用new
运算符delete
- 如果使用
为对象数组分配内存,请使用new[]
运算符delete[]
Customer
实例调用delete
(不带方括号)。这应该可以正常工作,因为所有Customer
对象都在循环中分配并添加到非共享容器中。本质上,您的链接列表“拥有”所有Customer
对象。在这种情况下,从列表中删除对象应触发解除分配。在可以从其他位置使用对象(即指针共享)的情况下,从列表中删除项目不应取消分配对象
<> >注意:这是一个非常低的水平。C++库提供了现成的列表容器,以及可以用来唯一的共享对象的智能指针,这大大简化了代码。 < P> C++中的规则有点不同:程序需要调用“代码>删除<代码>或<代码>删除】。operator,具体取决于用于分配内存的运算符
- 如果使用
为单个对象分配内存,请使用new
运算符delete
- 如果使用
为对象数组分配内存,请使用new[]
运算符delete[]
Customer
实例调用delete
(不带方括号)。这应该可以正常工作,因为所有Customer
对象都在循环中分配并添加到非共享容器中。本质上,您的链接列表“拥有”所有Customer
对象。在这种情况下,从列表中删除对象应触发解除分配。在可以从其他位置使用对象(即指针共享)的情况下,从列表中删除项目不应取消分配对象
<>注释:这是一个非常低的执行水平。C++库提供了现成的列表容器,以及可以用于唯一和共享对象的智能指针,这大大简化了代码。 < P>关于<强> RAII<强>资源占用是初始化,并使用<强>智能指针< /强>它们方便。资源管理(特别是分配的内存)了解RAII-资源获取是初始化,使用智能指针它们有助于资源管理(特别是分配的内存)使用
delete
释放分配给new
的内存是正确的。我假设数据库
属于customerlist
类型。在这种情况下,只要您没有意外地删除
或更改列表中的任何指针,您的代码就可以正常工作。这正是为什么您需要只有在绝对必要时才可以使用“裸new
”。在这种情况下,您可以尝试使用“std::unique\u ptr”:
while(fgets(stringBuf,100,dbFile))
{
// ...
std::unique_ptr<Customer> newEntry
{ new Customer(name,custID,credit,street,state,zip)};
database.insert(std::move(newEntry));
}
您使用
delete
释放分配给new
的内存是正确的。我假设database
属于customerlist
类型。在这种情况下,只要您没有意外地delete
或更改列表中的任何指针,您的代码就可以正常工作。这正是您应该这样做的原因只有在绝对必要时才使用“裸new
”。在这种情况下,您可以尝试使用“std::unique\u ptr”:
while(fgets(stringBuf,100,dbFile))
{
// ...
std::unique_ptr<Customer> newEntry
{ new Customer(name,custID,credit,street,state,zip)};
database.insert(std::move(newEntry));
}
您的
删除
功能似乎正确地删除了客户