指针列表初始化和释放内存
list of pointers initialize and release memory
使用list时有什么管理内存的好习惯,
在我们不再需要时动态分配和释放(免费)。为了保持程序轻便并避免内存泄漏,确保良好的内存管理(我现在这是一个广泛的问题)
- 如何初始化指向最初有 N 项的对象的指针列表?我应该使用 operator new 来分配内存吗?
- 如果我想从列表和程序内存中完全删除(释放)一个项目 space,我应该使用 pop 还是 remove 或 erase?差异?
- 我应该在迭代列表时使用运算符 delete 还是 .erase .remove 足以释放 space?
.
class myclass { /* whatever attributes, methodes */ };
list<myclass *> lst (5); //5 pointers will be NULL this way
for (list<myclass *>::iterator it=lst.begin(); it != lst.end(); it++) {
myclass *obj= *it;
delete obj; //error
it = lst.erase(it);
}
C++ 具有值语义。列表拥有其上的对象。无论是 int
(内置类型)、std::string
(库类型)还是 myclass
(您的)列表,都是如此。确保您的 class 可以被复制(或至少可以移动,但这是一个高级主题)。还要确保您的 class 析构函数正常工作,因为 list::clear
会调用它。
最初不要尝试使用指针列表。当你这样做时,使用 smart 指针列表,但这已经是一个高级主题。应完全避免 "dumb" 指针列表。
虽然我认为您应该听听其他人的意见,但我想我仍然会回答您的问题,以便您在需要了解时知道答案。智能指针绝对是现在最好用的,但是当我在 C++ 中学习指针时,我最初使用 new/delete 我觉得它比直接使用智能指针更能帮助你理解(我知道你说你不知道它们是什么,所以它们只是为您管理内存)。
how to initialize a list of pointers to objects initially with N items ? should i use the operator new to allocate memory?
正如您所做的那样,list<myclass *> lst (5)
就可以制作您的指针列表,是的,您应该为列表中的每个元素使用 new 以便在那里分配内存。例如,
list<myclass*>::iterator it = lst.begin();
*it = new myclass();
if i want to delete completely (free) an item from a list and program memory space, should i use pop or remove or erase ? differences?
要从列表中删除一个元素,您可以使用此处的列表擦除功能:http://www.cplusplus.com/reference/list/list/erase/
这将从列表中删除该元素,但是如果使用指针,请小心,因为您需要确保在删除此节点之前释放列表节点持有的指针(见下文)
should i use operator delete while iterating a list or .erase .remove is enough to free space ?
.erase 将从列表中删除该元素,但它不会为您释放指针,您将明确需要执行类似的操作。
list<myclass*> lst(5);
list<myclass*>::iterator it = lst.begin();
*it = new myclass();
// and when you're ready to delete a node
if(*it != NULL)
delete *it;
lst.erase(it);
此外,在你的 for 循环中,一定要像我一样检查指针在删除之前是否为 NULL。这可能是您在删除调用时出错的原因。既然不允许在NULL处存储内存,那么显然不允许删除那里的内存。那会给你一个分段错误。在删除之前检查 NULL 总是好的,以防万一,除非您确定它将保存数据。
希望这对您有所帮助。这不是使用较新版本的 C++ 的最佳方法,但它应该按要求回答您的问题。
- how to initialize a list of pointers to objects initially with N items ? should i use the operator new to allocate memory?
不要。让列表处理分配和释放。
lst.push_back(myclass());
如果您有许多项目要进入列表,您可以利用初始值设定项。下面使用一个myclass构造函数,以一个string和一个int为例
list<myclass> lst {{"one", 1},{"two", 2},{"three", 3}};
如果这是一个需要使用指针的赋值,绝对使用 new
而不是 malloc
并且它是分配存储空间的家族,但考虑这是最后的手段。
首选是使用智能指针。其中最大的两个是 unique_ptr and shared_ptr.
list<unique_ptr<myclass>> lst;
lst.push_back(unique_ptr<myclass>(new myclass()));
或在 C++14 或更新版本中,
lst.push_back(make_unique<myclass>());
当从列表中删除时,unique_ptr 会自动销毁 myclass。
但我认为这与直接包含我的class 的列表没有任何优势,除非我的class 是class 层次结构的基础class。如果您处于学习 C++ 的早期阶段,请在走这条路之前阅读和练习一些基础知识。
list<shared_ptr<myclass>> lst;
lst.push_back(shared_ptr<myclass>(new myclass()));
使我的 class 成为可与他人共享的引用计数。当每个用户都处理完他们的 shared_ptr 后,myclass 将被销毁。这对于具有回调的系统非常有用。当回调触发时,回调对象将在那里,防止各种有趣的段错误。缺点是对象的生命周期是模糊的。何时销毁取决于未完成的shared_ptrs.
不允许循环引用 shared_ptr,因为引用计数永远不会降为零。可能内置了一些非常偷偷摸摸的代码来提供帮助,但我不会指望它。反正程序设计不好。
原始指针 new
。只是不要这样做。您有更好、更安全的选择。
lst.push_back(new myclass());
- if i want to delete completely (free) an item from a list and program memory space, should i use pop or remove or erase ? differences?
remove
列表不存在。 pop,看你用哪个,要么去掉first or last element. Use pop if the list represents a queue or a stack. erase 可以去掉任何元素,只要你知道它在哪里。找到它可能需要搜索。
对于存储的对象,list<myclass>
您可能无法取回任何内存。该列表可能会保存分配的 RAM,因此以后不必再次请求它。坦率地说,我不确定列表的标准政策是什么。对于vectors, the object is destroyed, but the space remains allocated unless you manually force a resizing. I believe list behaves the same way because of the presence of the resize方法和文档的写法。
如果您有原始指针,则必须 delete
它,然后将其从列表中删除。您不能按其他顺序执行此操作,因为一旦从列表中删除,指针将无法访问并且您将丢失 RAM。是的,您可以复制指针,然后将其从列表中删除,然后删除副本,但为什么要付出额外的努力呢?我相信该指针仍将分配在列表中,但将无法访问并等待重用。
如果您使用 unique_ptr,unique_ptr 会为您处理。使用 shared_ptr,处置也会为您处理,但您不一定知道什么时候。 shared_ptr 的另一个副本可能存在,阻止破坏。
- should i use operator delete while iterating a list or .erase .remove is enough to free space ?
我在上面对 2 的回答中提到了。使用指针,从列表中删除只会删除指向 myclass 的指针,而不会留下指向 myclass 的指针,并且 RAM 会丢失.使用智能指针,myclass 被智能指针销毁,无需进一步努力。
但是如果 RAM 被列表保留以供重用,您可能不会收回任何明显数量的 RAM。
使用list时有什么管理内存的好习惯,
在我们不再需要时动态分配和释放(免费)。为了保持程序轻便并避免内存泄漏,确保良好的内存管理(我现在这是一个广泛的问题)
- 如何初始化指向最初有 N 项的对象的指针列表?我应该使用 operator new 来分配内存吗?
- 如果我想从列表和程序内存中完全删除(释放)一个项目 space,我应该使用 pop 还是 remove 或 erase?差异?
- 我应该在迭代列表时使用运算符 delete 还是 .erase .remove 足以释放 space?
.
class myclass { /* whatever attributes, methodes */ };
list<myclass *> lst (5); //5 pointers will be NULL this way
for (list<myclass *>::iterator it=lst.begin(); it != lst.end(); it++) {
myclass *obj= *it;
delete obj; //error
it = lst.erase(it);
}
C++ 具有值语义。列表拥有其上的对象。无论是 int
(内置类型)、std::string
(库类型)还是 myclass
(您的)列表,都是如此。确保您的 class 可以被复制(或至少可以移动,但这是一个高级主题)。还要确保您的 class 析构函数正常工作,因为 list::clear
会调用它。
最初不要尝试使用指针列表。当你这样做时,使用 smart 指针列表,但这已经是一个高级主题。应完全避免 "dumb" 指针列表。
虽然我认为您应该听听其他人的意见,但我想我仍然会回答您的问题,以便您在需要了解时知道答案。智能指针绝对是现在最好用的,但是当我在 C++ 中学习指针时,我最初使用 new/delete 我觉得它比直接使用智能指针更能帮助你理解(我知道你说你不知道它们是什么,所以它们只是为您管理内存)。
how to initialize a list of pointers to objects initially with N items ? should i use the operator new to allocate memory?
正如您所做的那样,list<myclass *> lst (5)
就可以制作您的指针列表,是的,您应该为列表中的每个元素使用 new 以便在那里分配内存。例如,
list<myclass*>::iterator it = lst.begin();
*it = new myclass();
if i want to delete completely (free) an item from a list and program memory space, should i use pop or remove or erase ? differences?
要从列表中删除一个元素,您可以使用此处的列表擦除功能:http://www.cplusplus.com/reference/list/list/erase/ 这将从列表中删除该元素,但是如果使用指针,请小心,因为您需要确保在删除此节点之前释放列表节点持有的指针(见下文)
should i use operator delete while iterating a list or .erase .remove is enough to free space ?
.erase 将从列表中删除该元素,但它不会为您释放指针,您将明确需要执行类似的操作。
list<myclass*> lst(5);
list<myclass*>::iterator it = lst.begin();
*it = new myclass();
// and when you're ready to delete a node
if(*it != NULL)
delete *it;
lst.erase(it);
此外,在你的 for 循环中,一定要像我一样检查指针在删除之前是否为 NULL。这可能是您在删除调用时出错的原因。既然不允许在NULL处存储内存,那么显然不允许删除那里的内存。那会给你一个分段错误。在删除之前检查 NULL 总是好的,以防万一,除非您确定它将保存数据。
希望这对您有所帮助。这不是使用较新版本的 C++ 的最佳方法,但它应该按要求回答您的问题。
- how to initialize a list of pointers to objects initially with N items ? should i use the operator new to allocate memory?
不要。让列表处理分配和释放。
lst.push_back(myclass());
如果您有许多项目要进入列表,您可以利用初始值设定项。下面使用一个myclass构造函数,以一个string和一个int为例
list<myclass> lst {{"one", 1},{"two", 2},{"three", 3}};
如果这是一个需要使用指针的赋值,绝对使用 new
而不是 malloc
并且它是分配存储空间的家族,但考虑这是最后的手段。
首选是使用智能指针。其中最大的两个是 unique_ptr and shared_ptr.
list<unique_ptr<myclass>> lst;
lst.push_back(unique_ptr<myclass>(new myclass()));
或在 C++14 或更新版本中,
lst.push_back(make_unique<myclass>());
当从列表中删除时,unique_ptr 会自动销毁 myclass。
但我认为这与直接包含我的class 的列表没有任何优势,除非我的class 是class 层次结构的基础class。如果您处于学习 C++ 的早期阶段,请在走这条路之前阅读和练习一些基础知识。
list<shared_ptr<myclass>> lst;
lst.push_back(shared_ptr<myclass>(new myclass()));
使我的 class 成为可与他人共享的引用计数。当每个用户都处理完他们的 shared_ptr 后,myclass 将被销毁。这对于具有回调的系统非常有用。当回调触发时,回调对象将在那里,防止各种有趣的段错误。缺点是对象的生命周期是模糊的。何时销毁取决于未完成的shared_ptrs.
不允许循环引用 shared_ptr,因为引用计数永远不会降为零。可能内置了一些非常偷偷摸摸的代码来提供帮助,但我不会指望它。反正程序设计不好。
原始指针 new
。只是不要这样做。您有更好、更安全的选择。
lst.push_back(new myclass());
- if i want to delete completely (free) an item from a list and program memory space, should i use pop or remove or erase ? differences?
remove
列表不存在。 pop,看你用哪个,要么去掉first or last element. Use pop if the list represents a queue or a stack. erase 可以去掉任何元素,只要你知道它在哪里。找到它可能需要搜索。
对于存储的对象,list<myclass>
您可能无法取回任何内存。该列表可能会保存分配的 RAM,因此以后不必再次请求它。坦率地说,我不确定列表的标准政策是什么。对于vectors, the object is destroyed, but the space remains allocated unless you manually force a resizing. I believe list behaves the same way because of the presence of the resize方法和文档的写法。
如果您有原始指针,则必须 delete
它,然后将其从列表中删除。您不能按其他顺序执行此操作,因为一旦从列表中删除,指针将无法访问并且您将丢失 RAM。是的,您可以复制指针,然后将其从列表中删除,然后删除副本,但为什么要付出额外的努力呢?我相信该指针仍将分配在列表中,但将无法访问并等待重用。
如果您使用 unique_ptr,unique_ptr 会为您处理。使用 shared_ptr,处置也会为您处理,但您不一定知道什么时候。 shared_ptr 的另一个副本可能存在,阻止破坏。
- should i use operator delete while iterating a list or .erase .remove is enough to free space ?
我在上面对 2 的回答中提到了。使用指针,从列表中删除只会删除指向 myclass 的指针,而不会留下指向 myclass 的指针,并且 RAM 会丢失.使用智能指针,myclass 被智能指针销毁,无需进一步努力。
但是如果 RAM 被列表保留以供重用,您可能不会收回任何明显数量的 RAM。