C++ 中对象的内存管理 收藏

发布于 2024-07-27 15:38:19 字数 505 浏览 1 评论 0原文

我有一个将整数与(对象的)向量相关联的映射。 这些向量代表一组要执行的任务。 为了减少使用此地图和矢量时进行的复制量,我将它们设置为使用指针。

std::map<int, std::vector<MyObject *> *> myMap;

在初始化保存 myMap 的类期间,我通过创建一个填充新 MyObject 的新向量来填充 myMap。

然而,我关心的是内存管理。 现在,我将这些不同的对象放在堆上的某个地方,我负责在使用完它们后清理它们。 我也知道在项目完成之前我永远不会完成他们的工作。 但是 10 周后,如果有人决定修改此应用程序的一个聪明方法是从地图/矢量中删除项目,该怎么办? 这会导致内存泄漏。

我的问题是如何处理这些对象的正确释放,以便即使它们通过 STL 函数被删除,对象也能成功释放?

非常感谢您的帮助,如果我错过了任何重要的内容,请告诉我! 谢谢!

I have a map that relates integers to vectors (of objects). These vectors represent a set of tasks to perform. In order to reduce the amount of copying going on while using this map and vector I've set them up to make use of pointers.

std::map<int, std::vector<MyObject *> *> myMap;

During initialization of the class that holds myMap, I populate myMap by creating a new vector filled with new MyObjects.

What I'm concerned with, however, is memory management. Now I have these various objects sitting out on the heap somewhere and I am responsible for cleaning them up when I'm done with them. I also know that I will NEVER be done with them until the program is finished. But what about in 10 weeks when someone decides that a clever way to modify this app involves removing items from the map/vectors. This would cause a memory leak.

My question is how can I handle the proper deallocation of these objects so that even if they get removed via an STL function that the objects get successfully deallocated?

Your help is much appreciated, let me know if I've missed anything critical!
Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

天涯沦落人 2024-08-03 15:38:19

使用智能指针 boost:shared_ptr 而不是原始指针,这样当对象被销毁时,它也会清除堆分配的内存。

boost::shared_ptr http://www.boost.org/ doc/libs/1_39_0/libs/smart_ptr/shared_ptr.htm

另外,真的有理由拥有指向向量的指针吗? 它们几乎不占用空间,并且 std::map 中的对象无论如何都不会移动(与每次向量重新分配时移动/复制向量中的对象不同,例如为了获得更多空间)。

编辑:
另外,shared_ptr 是 tr1 的一个组件,我很确定它会出现在下一个标准中,因此您的编译器可能已经有了它。 还有许多其他 STL 安全的智能指针可以让您了解如何编写自己的智能指针,在 Google 上快速搜索应该可以找到它们。

编辑2:
刚刚检查,TR1 的 Visual Studio 2008 实现包括共享指针,该指针包含在 Visual C++ 2008 功能包。 我预计许多其他供应商至少可以实现 TR1 的部分功能,因此,如果您不使用 VS,请在您的供应商网站上搜索 TR1 支持。

Use a smart pointer boost:shared_ptr rather than raw pointers, that way when the object is destroyed it will clear up the heap allocated memory as well.

boost::shared_ptr http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/shared_ptr.htm

Also is there really a reason to have pointers to the vectors? They take up almost no space, and objects within an std::map are not moved anyway (unlike the objects in a vector which are moved/copied each time the vector reallocates, eg to get more space).

EDIT:
Also shared_ptr is a component of tr1, and I'm pretty sure is in the next standard, so your compiler may already have it. There are also lots of other smart pointers around that are STL safe to give you an idea of how to write your own, a quick search on Google should find them.

EDIT2:
Just checked and the Visual Studio 2008 implementation of TR1 includes the shared_ptr which is included in the Visual C++ 2008 Feature Pack. I expect many other vendors have implementations available for at least parts of TR1, so if your not using VS search your vendors site for TR1 support.

只为守护你 2024-08-03 15:38:19

我同意使用智能指针是一个好方法,但至少有两种选择:

a)复制可能不像您想象的那么昂贵。 尝试实现值映射

std::map<int, std::vector<MyObject>> myMap;

b) 将向量替换为您自己的包装该向量的类。 在该类的析构函数中,处理释放。 您还可以提供添加和删除 MyObject 的方法。

I agree the use of smart pointers is a good way to go, but there are at least two alternatives:

a) Copying may not be as expensive as you think it is. Try implementing a map of values

std::map<int, std::vector<MyObject>> myMap;

b) Replace the vector with a class of your own that wraps the vector. In that classes destructor, handle the deallocation. You could also provide methods for adding and removing MyObjects.

北方的巷 2024-08-03 15:38:19

使用共享指针(如其他人建议的那样)是最好的解决方案。

如果您确实知道您将永远不会使用它们,那么从技术上讲它们就不需要解除分配。 如果这确实是所需的行为,只需将其记录下来,这样 10 周内就不会有人出现并将其误认为是真正的泄漏。

Using a shared pointer (as suggested by others) is the best solution.

If you really know you will never be done with them, then they don't technically need deallocating. If this really is desired behaviour, just document it so that someone doesn't come along in 10 weeks and mistake this for a genuine leak.

请爱~陌生人 2024-08-03 15:38:19

谢谢大家的好回答。 我认为目前我倾向于采用价值向量解决方案。 主要原因是 std::auto_ptr 不适用于集合,因为它是不可复制的。 这将是我能够使用的智能指针的唯一实现,而无需经过繁琐的审查过程或自行滚动。

好消息是您的回答引导我走上了一条非常好的道路。 我了解了 RAII、异常处理的危险以及如何将其最小化,并对我的设计投入了足够的警惕,以便我对其“正确性”感到满意。

附上一些我发现很有帮助的链接。 我希望任何遇到类似问题的人都会发现这些链接很有帮助。

RAII 资源
C++ 中的智能指针
Boost 智能指针
有关智能指针的更多背景/实现详细信息

Thank you all for the good answers. I think currently I'm leaning towards a vector of values solution currently. The main reason is that std::auto_ptr doesn't work with collections due to the fact that it is uncopyable. This would be the only implementation of a smart pointer that I would be able to use without going through a burdensome vetting process or rolling my own.

The good news is your responses led me down a very good road. I learned about RAII, dangers about exception handling and how to minimize them, and put enough vigilance into my design that I can be satisfied with its "Correctness".

Attached are some links that I found helpful along the way. I hope that anyone coming to a similar problem will find these links helpful.

RAII Resource
Smart Pointers in C++
Boost Smart Pointers
More background/implementation details about Smart pointers

好久不见√ 2024-08-03 15:38:19

如果每个指针的所有权不在向量/映射中的不同条目之间共享,因此您仅意味着减少插入时完成的复制,那么您还应该考虑 boost 的 指针容器库。

If the ownership of each pointer is not shared among different entries in the vectors/maps and so you only mean reducing the copying done at insertion time, then you should also consider boost's Pointer Container library.

这样的小城市 2024-08-03 15:38:19

详细说明如何在使用 map<,vector> 时最小化复制:

仔细查看 mapvector 的接口。 它们大多返回对所包含项目的引用,如果您在传递这些内容时保留引用,则不会发生复制。

坏例子:

std::vector<MyObject> find_objects( const std::map<int,std::vector<MyObject>> & map, int i ) {
    const std::map<int,std::vector<MyObject>>::const_iterator it = map.find( i );
    if ( it != map.end() )
        return it->second;
    else
        return std::vector<MyObject>();
}
// ...
const std::vector<MyObject> objects = find_objects(/*...*/);

更好:

const std::vector<MyObject> & find_objects( const std::map<int,std::vector<MyObject>> & map, int i ) {
    const std::map<int,std::vector<MyObject>>::const_iterator it = map.find( i );
    if ( it != map.end() )
        return it->second;
    static const std::vector<MyObject> none();
    return none;
}
// ...
const std::vector<MyObject> & objects = find_objects(/*...*/);

-> 禁止复制

To elaborate on minimizing copying when using map<,vector<Object>>:

Closely look at the interfaces of map and vector. They mostly return references to the contained items, and if you preserve the reference in passing these things around, no copying will occur.

Bad example:

std::vector<MyObject> find_objects( const std::map<int,std::vector<MyObject>> & map, int i ) {
    const std::map<int,std::vector<MyObject>>::const_iterator it = map.find( i );
    if ( it != map.end() )
        return it->second;
    else
        return std::vector<MyObject>();
}
// ...
const std::vector<MyObject> objects = find_objects(/*...*/);

Better:

const std::vector<MyObject> & find_objects( const std::map<int,std::vector<MyObject>> & map, int i ) {
    const std::map<int,std::vector<MyObject>>::const_iterator it = map.find( i );
    if ( it != map.end() )
        return it->second;
    static const std::vector<MyObject> none();
    return none;
}
// ...
const std::vector<MyObject> & objects = find_objects(/*...*/);

-> no copying

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文