容器元素增删内存变化浅析

前言

STL的容器模板类在添加元素的时候,采用拷贝构造,并且是浅拷贝,而不是直接传递指针,这意味这系统要多开辟一块内存来满足容器的使用。如果要正确使用STL容器对各种对象操作要注意重载拷贝构造函数,也就是变成深拷贝

使用细节

测试代码使用到了vector向量,而每次他都调用当前元素相应个数的析构以及拷贝构造。这其中的原因是vector初始化大小为1,然后每次添加元素进去它都会改变大小来满足元素个数的需要,而当添加到第三个的时候它大小直接开辟两个,后面变为4个(如例输出)。这就和数据结构中顺序表具体操作有关,大胆猜测一下这个大小当到达某个阈值时就会线性增加,而不会翻倍


测试代码

#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
using namespace std;

class STL_Test{
public:
    char *str;

public:
    STL_Test():str(NULL){
        cout << "构造函数调用" << endl;
    }
    STL_Test(const STL_Test &cd)
    {
        cout << "拷贝函数调用 " << endl;
        this->str = new char[strlen(cd.str)+1];
        strcpy(str, cd.str);
    }

    ~STL_Test(){
        if(str){
            cout << "析构函数调用,str不为null" << endl;
            delete[] str;
        }else {
            cout << "析构函数" << endl;
        }
    }
};

int main()
{
    vector <STL_Test> a2;// = new vector <STL_Test>();
    vector <STL_Test> *a1 = &a2;
    a1 -> reserve(1);
    cout << "容器大小: " << a1 -> capacity() << endl;

    STL_Test d1;
    d1.str = new char[32];
    strcpy(d1.str, "copy1");
    cout << "---------------------------------" << endl;
    a1->push_back(d1);
    cout << "---------------------------------" << endl;

    STL_Test d2;
    d2.str = new char[32];
    strcpy(d2.str, "copy2");
    cout << "---------------------------------" << endl;
    cout << a1 <<endl;
    a1->push_back(d2);
    cout << "容器大小: " << a1 -> capacity() << endl;
    cout << a1 <<endl;
    cout << "---------------------------------" << endl;

    STL_Test d3;
    d3.str = new char[32];
    strcpy(d3.str, "copy3");
    cout << "---------------------------------" << endl;
    cout << a1 <<endl;
    (*a1).push_back(d3);
    cout << "容器大小: " << a1 -> capacity() << endl;
    cout << a1 <<endl;
    cout << "---------------------------------" << endl;

    STL_Test d4;
    d4.str = new char[32];
    strcpy(d4.str, "copy4");
    cout << "---------------------------------" << endl;
    cout << a1 <<endl;
    a2.push_back(d4);
    a2.push_back(d4);
    cout << "容器大小: " << a2.capacity() << endl;
    cout << a1 <<endl;
    cout << "---------------------------------" << endl;

//  delete a1;这里删除a2栈内存空间,让程序不能正常结束

    return 0;
}

原文地址:https://www.cnblogs.com/caczhtus/p/10350828.html

时间: 2024-10-20 02:08:43

容器元素增删内存变化浅析的相关文章

内存管理 浅析 内存管理/内存优化技巧

内存管理 浅析 下列行为都会增加一个app的内存占用: 1.创建一个OC对象: 2.定义一个变量: 3.调用一个函数或者方法. 如果app占用内存过大,系统可能会强制关闭app,造成闪退现象,影响用户体验.如何让回收那些不再使用的对象呢?本文着重介绍OC中的内存管理. 所谓内存管理,就是对内存进行管理,涉及的操作有: 1.分配内存:比如创建一个对象,会增加内存占用: 2.清除内存:比如销毁一个对象,会减少内存占用. 内存管理的管理范围: 1.任何继承了NSObject的对象: 2.对其他非对象类

vector动态二维数组(容器的容器)占用内存分析

之前在这里写过一篇"C++中的动态二维数组".在C++中没有动态二维(多维)数组.但是根据原理我们可以自己创建. 在看过STL的vector源代码后"<STL源码剖析>---stl_vector.h阅读笔记"后,想到可以用容器的容器来做二维数组. 创建一个2x4的二维数组.想到的办法是:先创建一个容器的容器,外层大小的2(2行),然后里面容器小大为4(4列). int row=2,col=4; vector<vector<int> &g

滚动锚定(Scroll Anchoring)- 让视口内容不再因视口上方 DOM 元素的高度变化而产生跳动

不知道你有没有经历过这样的场景:当你打开一张“多图杀猫”的页面后,正一张图一张图边滚边看,在你刚准备定睛看某一张图的时候,这张图突然被它上面的内容挤到了视口下方,然后你赶紧把滚动条往下拉,试图追赶这张没看完的图,当你刚刚追上的时候,这张图又一次被挤到了你看不见的地方. 发生这种情况的原因是因为在很多场景下(比如论坛里),你没法事先知道一张图的高度,所以你没法事先给这张图占位,在网速不理想的情况下,可能就会发生我上面描述的这种因页面靠上的图片比靠下的图片晚加载出来而导致用户当前浏览的内容被频繁挤出

C++ 安全并发访问容器元素

C++ 安全并发访问容器元素 2014-9-24 flyfish 标准库STL的vector, deque, list等等不是线程安全的 例如 线程1正在使用迭代器(iterator)读vector 线程2正在对该vector进行插入操作,使vector重新分配内存,这样就造成线程1中的迭代器失效 STL的容器 多个线程读是安全的,在读的过程中,不能对容器有任何写入操作 多个线程可以同时对不同的容器做写入操作. 不能指望任何STL实现来解决线程难题,必须手动做同步控制. 方案1 对vector进

linux内存管理浅析

[地址映射](图:左中)linux内核使用页式内存管理,应用程序给出的内存地址是虚拟地址,它需要经过若干级页表一级一级的变换,才变成真正的物理地址.想一下,地址映射还是一件很恐怖的事情.当访问一个由虚拟地址表示的内存空间时,需要先经过若干次的内存访问,得到每一级页表中用于转换的页表项(页表是存放在内存里面的),才能完成映射.也就是说,要实现一次内存访问,实际上内存被访问了N+1次(N=页表级数),并且还需要做N次加法运算.所以,地址映射必须要有硬件支持,mmu(内存管理单元)就是这个硬件.并且需

VB6之多维数组中元素在内存中的排列情况

1 Private Declare Sub RtlMoveMemory Lib "kernel32" (Destination As Any, Source As Any, ByVal Length As Long) 2 3 4 'code by lichmama from cnblogs.com 5 Private Sub Form_Load() 6 Dim a(2) As Byte 7 Dim b(2, 2) As Byte 8 Dim c(2, 2, 2) As Byte 9 1

stl容器之--自定义结构体作为stl容器元素成员的使用

自定义结构体作为stl容器元素成员的设计要求之一是:在对待自定义类型时和内置类型必须是一致的,甚至自定义类型的支持更好. <C++标准程序库>: set和multiset set和multiset会根据特定的排序准则,自动将元素排序.两者不同在于multiset允许重复而set不允许. 只要是assignable.copyable.comparable(根据某个排序准则)的型别T,都可以成为set或multiset的元素型别.没有传入特别排序准则,就采用缺省准则less(这是一个仿函数,以op

Docker: 限制容器可用的内存

原文:Docker: 限制容器可用的内存 默认情况下容器使用的资源是不受限制的.也就是可以使用主机内核调度器所允许的最大资源.但是在容器的使用过程中,经常需要对容器可以使用的主机资源进行限制,本文介绍如何限制容器可以使用的主机内存. 为什么要限制容器对内存的使用? 限制容器不能过多的使用主机的内存是非常重要的.对于 linux 主机来说,一旦内核检测到没有足够的内存可以分配,就会扔出 OOME(Out Of Memmory Exception),并开始杀死一些进程用于释放内存空间.糟糕的是任何进

C++ 容器元素的存储和获取

1.存储对象,存储的是对象的副本,并不是原对象.2.获取对象,获取的是对象的引用,为什么要这样设计? a.存储对象只发生一次,而获取对象往往会有多次,获取对象,如果每次都返回对象的副本,这个开销很大. b.考虑下面的情况,修改容器中的对象,如果获取对象,返回的是副本而不是引用,没有办法修改容器中元素的值.容器必须提供另外一种方法,可以修改对象.3.对于c[i] 获取容器c中的元素.考虑,引用容器并不存在的元素,这个时候容器该怎么处理?容器有两种做法:a.不做检查,直接返回对应的地址.b.检查是否