Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何正确管理动态分配对象的内存?_C++_Memory Management - Fatal编程技术网

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));
}

您的
删除
功能似乎正确地删除了
客户