动态内存分配与C ++中用户定义的类的自动分配之间的区别

问题描述 投票:1回答:1

我有一个类“ DMRecSessionObj”,它具有两个整数,一个字符串和一个向量作为其数据成员。

class DMRecSessionObj
{
private:
    int callNum;
    int totCalls;
    std::string sessionKey;
    std::vector<DMRecord>RecList;
public:
   ...
};

创建DMRecSessionObj对象后,根据需要将向量RecList的大小推入时,向量RecList的大小将约为150000。几个此类DMRecSessionObj对象将存储在静态映射中。

static std::map<string,DMRecSessionObj*> mapExpSessData;

所以,我想知道创建DMRecSessionObj对象的更好的选择。

DMRecSessionObj* dmRec = new DMRecSessionObj(); //Dynamic memory allocation
DMRecSessionObj dmRecSessionObj; //Automatic memory allocation

问这个问题的目的是要了解在这两种情况下都需要注意的影响。

  1. 动态内存分配
  2. 由编译器自动分配内存

请考虑较高的内存要求作为方案,提出更好的选择。

提前感谢

c++ memory-management
1个回答
0
投票

作为粗略的经验,如果直接使用运算符new,则应考虑使用标准容器(std::vectorstd::map等),避免使用原始指针并且不要直接使用运算符new

作为另一个粗略的经验法则,如果您使用大量内存(例如,由于数组或地图较大),则应再次考虑使用可调整大小的标准容器(即可以增长以容纳更多元素的容器或一个较大的映射),例如std::vectorstd::map,而不是std::array(在编译时已设置大小)。

这两个经验法则的原因是,可调整大小的标准容器执行动态内存分配,可以自动调整自身大小(当您使用规则时按规则进行操作)。实际上,与使用静态或自动存储持续时间的变量或对象(使用不准确的称为“堆内存”的对象)相比,使用动态内存分配(使用不准确的称为“堆内存”)的程序可以分配更多的内存。堆栈内存”,实际上该程序可用的“堆栈内存”少于“堆内存”)。

鉴于您的描述,如果我要使用static映射,则将其更改为;

static std::map<std::string,DMRecSessionObj> mapExpSessData;   // note no pointer here

然后使用这样的循环来使用代码填充它(从概念上讲,可能在循环体内)

std::string string key = obtain_string_from_somewhere();
DMRecSessionObj object = read_object_from_somewhere();
mapExpSessData[key] = object;

这使映射可以照顾自己的动态内存分配。这样,如果您需要管理地图的内容(例如,删除条目或添加条目),则可以使用std::map为此目的提供的操作。如果正确使用这些操作,通常可以正确清理内存(例如,不会发生泄漏,因为当您从地图中删除条目时,您忘记释放使用操作员new手动创建的对象)。

以上对象keyobject是自动创建的,这意味着它们在完成作用域后将不复存在。从技术上讲,在您填充地图时,MAY(不一定会)会导致存在其他对象)。我建议如果地图很大,则其他对象无关紧要。

注意,通常,需要收集150000个对象(甚至是很小的对象)的程序通常可以合理化。如果一个程序在一个映射(或任何容器)中有150000个对象,那么实际上,通常会发现该程序实际上使用了很少的对象。因此,最好进行一些设计工作以预测或估计内存中实际需要哪些对象,从而实现较小的映射或向量。这可能涉及权衡取舍,例如需要从存储中读取不经常使用的对象,而不是始终将它们放在映射中-但是会大大减少程序的内存使用量。这可以在许多设置中显着提高性能-例如,程序在资源有限的计算机上运行,​​或者由承载其他程序的操作系统承载,并且需要在内存和交换之间定期交换执行程序空间(在磁盘上)以确保所有程序都能运行。

请记住,使用static变量也会带来巨大的损失。如果进行搜索,则会发现很多解释,为什么通常最好避免使用static变量以及替代方法是什么。


0
投票

对象的自动内存分配仅对于作为POD的对象的成员发生。

© www.soinside.com 2019 - 2024. All rights reserved.