Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.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++_Pointers_Vector_Delete Operator - Fatal编程技术网

C++ 为什么要在实例替换的向量中删除?

C++ 为什么要在实例替换的向量中删除?,c++,pointers,vector,delete-operator,C++,Pointers,Vector,Delete Operator,这不是一个实际问题,但只是出于教育好奇心 在某个论坛中,我刚刚发现了以下代码: std::vector<MyClass*> myvec; for(unsigned int i = 0; i < 100; ++i) {   myvec.push_back(new MyClass( foo1 )); } // somewhere in the code inside a particular if statement MyClass* replacement = new MyCl

这不是一个实际问题,但只是出于教育好奇心

在某个论坛中,我刚刚发现了以下代码:

std::vector<MyClass*> myvec;
for(unsigned int i = 0; i < 100; ++i) {
  myvec.push_back(new MyClass( foo1 ));
}

// somewhere in the code inside a particular if statement
MyClass* replacement = new MyClass( foo2 );
delete myvec[0];
myvec[0] = replacement;
我有一个MyClass实例的向量,在代码的某个地方,我必须用其他实例替换一些实例

为什么我必须调用delete?更换指针还不够吗

我学到的是: 外面有个魔鬼叫 对于每个对new的调用,您应该在代码中的某个地方有一个相应的要删除的调用。 我可以使用共享指针。。 我可以用valgrind 如果不删除原始MyClass,它将保留,但无法访问,因为您删除了指向它的指针。这是一个好主意

请注意,如果初始分配中的任何新表达式(第一个表达式除外)抛出,则您正在泄漏先前分配的元素

所有这些都可以通过不使用指针向量而使用简单的std::vector来避免,或者如果您确实需要,可以使用智能指针来避免。

如果您不删除原始MyClass,它将保留,但无法访问,因为您删除了指向它的指针。这是一个好主意

请注意,如果初始分配中的任何新表达式(第一个表达式除外)抛出,则您正在泄漏先前分配的元素


所有这些都可以通过使用简单的std::vector而不是指针向量来避免,或者如果确实需要,可以通过使用智能指针来避免。

您需要显式释放内存,否则它将保持已分配状态,但无法访问。这不是Java或C语言,垃圾收集器将处理它。

您需要显式释放内存,否则它将保持分配状态,但无法访问。这不是垃圾收集器将处理的Java或C。

std::vector是指针向量。它不管理它所持有的对象的生命周期——它只管理指向它所表示的指针数组的内存

如果您没有正确管理删除,您将以泄漏告终,除非您从另一个错误中删除两次。

std::vector是指针向量。它不管理它所持有的对象的生命周期——它只管理指向它所表示的指针数组的内存


如果您没有正确管理删除操作,则将导致泄漏,除非您从另一个错误中删除两次。

标准指针容器永远不会删除其包含的任何指针的目标。它无法知道它们指向用new创建的对象-它们可能是用new[]创建的,在这种情况下需要delete[],或者它们可能是指向静态或自动对象的指针,这些对象不能被删除,或者可能有其他东西负责删除它们

通常,您会将对象存储在容器中,而不是指针中。如果您真的需要指针,可能是因为对象需要不同的类型,并且您确实需要那些指针来管理对象生存期,考虑使用一个智能指针,如STD::UnQuyJ-PTR,它自动删除其目标,或者如果没有可用的话,Booo::PtR矢向量。
否则,如果您真的必须使用原始指针来管理对象生命周期,那么您必须小心在正确的时间使用delete。在这种情况下,诸如之类的工具可以帮助识别不可避免的内存泄漏。

指针的标准容器永远不会删除它所包含的任何指针的目标。它无法知道它们指向用new创建的对象-它们可能是用new[]创建的,在这种情况下需要delete[],或者它们可能是指向静态或自动对象的指针,这些对象不能被删除,或者可能有其他东西负责删除它们

通常,您会将对象存储在容器中,而不是指针中。如果您真的需要指针,可能是因为对象需要不同的类型,并且您确实需要那些指针来管理对象生存期,考虑使用一个智能指针,如STD::UnQuyJ-PTR,它自动删除其目标,或者如果没有可用的话,Booo::PtR矢向量。 否则,如果您真的必须使用原始指针来管理对象生命周期,那么您必须小心在正确的时间使用delete。在这种情况下,诸如之类的工具可以帮助识别不可避免的内存泄漏。

当您调用

new MyClass( foo1 )
在堆中分配内存以存储类MyClass的对象。 此内存将一直保持分配状态,直到您使用delete释放它为止

因此,对于每次调用new,您都应该有一个相应的调用来删除代码中的某个地方。

当您调用

new MyClass( foo1 )
在堆中分配内存以存储类MyClass的对象。 此内存将一直保持分配状态,直到您使用delete释放它为止

因此,对于每个对new的调用,您应该在代码中的某个地方有一个相应的要删除的调用。

在向量中,您存储了指向内存mallo的指针
你自己去吧。如果你只是替换了向量的一个元素,向量对内存没有任何作用,也许某个类会自动释放内存,但向量不会这样做。我认为你可以在正常数组中考虑同样的条件而不是向量。

在你的向量中,你存储了指针,指向你自己错位的内存。如果你只是替换了向量的一个元素,向量对内存没有任何作用,也许某个类会自动释放内存,但向量不会这样做。C++中的最大问题之一是在对象向量中存储的类型。

如果对象是默认的可构造、可复制和可分配的,则可以存储实例向量,但如果复制和分配成本很高,则将它们存储在向量中也可能如此。此外,如果检索要修改的值,则需要检索引用。但是,如果在保持该引用的同时向量发生变化,则引用可能无效

您可以存储指针向量,正如您所做的那样。然后您需要管理指针的生命周期,因为向量不会

您可以存储共享_ptr的向量,这通常是这样做的。这并不理想,因为对象的所有权可能在向量中。这样做不会有麻烦,但这不是处理大量对象的最佳方式

boost提供了一个特殊的指向指针的向量,可以为您管理生命周期。可以是一个很好的选择

新的C++11将允许移动对象的向量,我认为唯一的向量可能也允许,自动向量则不允许

这相当主观,但理想的做法是将typedef定义为指针类型,然后使用该typedef的向量。如果适合,您可以稍后更改typedef。共享的ptr可能会帮你完成这项工作

现在结果是这样的:

typedef spns::shared_ptr< MyClass > MyClassPtr; 
      // spns is an alias to the namespace you use for shared_ptr, either std or boost
std::vector<MyClassPtr> myvec;
for(unsigned int i = 0; i < 100; ++i) 
{
  myvec.push_back(MyClassPtr( new MyClass( foo1 ));
  // but with C++11 if you still use shared_ptr replace with
 // myvec.push_back( spns::make_shared<MyClass>(foo1) );
}

// somewhere in the code inside a particular if statement
MyClass* replacement = new MyClass( foo2 );
myvec[0] = MyClassPtr( replacement );

 // preferred alternative to above 2 lines
 //  myvec[0].reset( new MyClass(foo2) );

<> > C++中最大的问题之一是要在对象向量中存储什么类型。 如果对象是默认的可构造、可复制和可分配的,则可以存储实例向量,但如果复制和分配成本很高,则将它们存储在向量中也可能如此。此外,如果检索要修改的值,则需要检索引用。但是,如果在保持该引用的同时向量发生变化,则引用可能无效

您可以存储指针向量,正如您所做的那样。然后您需要管理指针的生命周期,因为向量不会

您可以存储共享_ptr的向量,这通常是这样做的。这并不理想,因为对象的所有权可能在向量中。这样做不会有麻烦,但这不是处理大量对象的最佳方式

boost提供了一个特殊的指向指针的向量,可以为您管理生命周期。可以是一个很好的选择

新的C++11将允许移动对象的向量,我认为唯一的向量可能也允许,自动向量则不允许

这相当主观,但理想的做法是将typedef定义为指针类型,然后使用该typedef的向量。如果适合,您可以稍后更改typedef。共享的ptr可能会帮你完成这项工作

现在结果是这样的:

typedef spns::shared_ptr< MyClass > MyClassPtr; 
      // spns is an alias to the namespace you use for shared_ptr, either std or boost
std::vector<MyClassPtr> myvec;
for(unsigned int i = 0; i < 100; ++i) 
{
  myvec.push_back(MyClassPtr( new MyClass( foo1 ));
  // but with C++11 if you still use shared_ptr replace with
 // myvec.push_back( spns::make_shared<MyClass>(foo1) );
}

// somewhere in the code inside a particular if statement
MyClass* replacement = new MyClass( foo2 );
myvec[0] = MyClassPtr( replacement );

 // preferred alternative to above 2 lines
 //  myvec[0].reset( new MyClass(foo2) );

一个更好的问题:为什么首先要存储指针?要查找泄漏,只需使用valgrind-leak check=full运行程序……这是一个非常实用的问题。内存管理错误会给团队带来严重的麻烦。一个更好的问题是:为什么首先存储指针?要查找泄漏,只需使用valgrind-leak check=full运行程序……这是一个非常实际的问题。内存管理错误可能会使团队陷入严重的麻烦。