我有一个类“ 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
问这个问题的目的是要了解在这两种情况下都需要注意的影响。
请考虑较高的内存要求作为方案,提出更好的选择。
提前感谢
作为粗略的经验,如果直接使用运算符new
,则应考虑使用标准容器(std::vector
,std::map
等),避免使用原始指针并且不要直接使用运算符new
。
作为另一个粗略的经验法则,如果您使用大量内存(例如,由于数组或地图较大),则应再次考虑使用可调整大小的标准容器(即可以增长以容纳更多元素的容器或一个较大的映射),例如std::vector
和std::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
手动创建的对象)。
以上对象key
和object
是自动创建的,这意味着它们在完成作用域后将不复存在。从技术上讲,在您填充地图时,MAY(不一定会)会导致存在其他对象)。我建议如果地图很大,则其他对象无关紧要。
注意,通常,需要收集150000个对象(甚至是很小的对象)的程序通常可以合理化。如果一个程序在一个映射(或任何容器)中有150000个对象,那么实际上,通常会发现该程序实际上使用了很少的对象。因此,最好进行一些设计工作以预测或估计内存中实际需要哪些对象,从而实现较小的映射或向量。这可能涉及权衡取舍,例如需要从存储中读取不经常使用的对象,而不是始终将它们放在映射中-但是会大大减少程序的内存使用量。这可以在许多设置中显着提高性能-例如,程序在资源有限的计算机上运行,或者由承载其他程序的操作系统承载,并且需要在内存和交换之间定期交换执行程序空间(在磁盘上)以确保所有程序都能运行。
请记住,使用static
变量也会带来巨大的损失。如果进行搜索,则会发现很多解释,为什么通常最好避免使用static
变量以及替代方法是什么。
对象的自动内存分配仅对于作为POD的对象的成员发生。