C++ std::vector元素的内存分配问题
2016-01-17 22:11
567 查看
来看一个问题:
在使用C++ STL的vector时,下面三种写法有什么不同呢?其内存分配是怎么样的呢?
首先,说结论吧(假设T是一个定义好的类):
对于
对于
对于
下面通过实验说说第一种情况和第二种情况的不同吧!
下面代码中声明了一个类A和一个函数IsObjectOnStack()用于监测对象是否在栈上,该函数使用到了Windows的系统API。
下面做第一种情况的测试:
运行结果:
运行结果" title="">可以看到
第三种情况测试:
运行结果:
运行结果" title="">这个很明显
所以,我个人觉得两者的主要区别在于:
在使用C++ STL的vector时,下面三种写法有什么不同呢?其内存分配是怎么样的呢?
std::vector<T> vec; std::vector<T>* Vec = new std::vector<T>(); std::vector<T*> vec;
首先,说结论吧(假设T是一个定义好的类):
对于
std::vector<T> vec;vec在栈上(stack),而其中的元素T保存在堆上(heap);
对于
std::vector<T>* Vec = new std::vector<T>();vec和其中的元素T都保存在堆上;
对于
std::vector<T*> vec;vec在栈上(stack),而其中的元素T保存在堆上(heap);和第一种情况类似。
下面通过实验说说第一种情况和第二种情况的不同吧!
下面代码中声明了一个类A和一个函数IsObjectOnStack()用于监测对象是否在栈上,该函数使用到了Windows的系统API。
#include <vector> #include <iostream> #include <Windows.h> using std::vector; using std::cout; class A { public: A(); //构造函数 A(const A& a); //拷贝构造函数 ~A(); //析构函数 }; A::A() { cout << "A的构造函数..." << '\n'; } A::A(const A& a) { cout << "A的拷贝构造函数..." << '\n'; } A::~A() { cout << "A的析构函数..." << '\n'; } BOOL IsObjectOnStack(LPVOID pObject) { INT nStackValue(0); MEMORY_BASIC_INFORMATION mi = { 0 }; DWORD dwRet = VirtualQuery(&nStackValue, &mi, sizeof(mi)); if (dwRet > 0) { return pObject >= mi.BaseAddress && (DWORD)pObject < (DWORD)mi.BaseAddress + mi.RegionSize; } return FALSE; }
下面做第一种情况的测试:
int main() { vector<A> aa; int nCount = 2; for (int i = 0; i < nCount; i++) { A a; BOOL isOnStack = IsObjectOnStack(&a); if (isOnStack) cout << "对象a在栈上创建..." << '\n'; else cout << "对象a在堆上创建..." << '\n'; aa.push_back(a); } BOOL isOnStack = IsObjectOnStack(&(aa.at(0))); if (isOnStack) cout << "std::vector中元素在栈上创建..." << '\n'; else cout << "std::vector中元素在堆上创建..." << '\n'; return 0; }
运行结果:
运行结果" title="">可以看到
std::vector<A>中的元素A是在栈上创建的。而且是在push_back的时候将栈上对象通过拷贝复制到堆上去的。
第三种情况测试:
int main() { vector<A*> aa; int nCount = 2; for (int i = 0; i < nCount; i++) { A* a = new A(); BOOL isOnStack = IsObjectOnStack(a); if (isOnStack) cout << "对象a在栈上创建..." << '\n'; else cout << "对象a在堆上创建..." << '\n'; aa.push_back(a); } BOOL isOnStack = IsObjectOnStack(aa.at(0)); if (isOnStack) cout << "std::vector中元素在栈上创建..." << '\n'; else cout << "std::vector中元素在堆上创建..." << '\n'; for (int i = 0; i < nCount; i++) { delete aa.at(i); } return 0; }
运行结果:
运行结果" title="">这个很明显
std::vector<A*>中的对象都是在堆上。使用完以后,我们必须手动释放该对象所占内存。
所以,我个人觉得两者的主要区别在于:
std::vector<T>和
std::vector<T*>中元素T都是存储在栈上,而且
std::vector<T>不用手动管理内存空间,而
std::vector<T*>需要手动delete释放栈上的空间。但是push_back的时候
std::vector<T>会比
std::vector<T*>多一个拷贝构造的过程。
相关文章推荐
- C++编程对缓冲区的理解
- 【LeetCode-242】Valid Anagram(C++)
- C语言中的三大循环
- C++学习笔记44——动态绑定
- 在考C++的前一天晚上(一天的学习总结)
- C++中数字与字符串之间的转换
- C++和C的相互调用
- C++11新特性应用--介绍几个新增的便利算法(不更改容器中元素顺序的算法)
- C++11新特性应用--介绍几个新增的便利算法(不更改容器中元素顺序的算法)
- C/C++——C++中new与malloc的10点区别
- C++ 输入函数getline(cin,str) 与cin.getline(str,int)区别
- C++学习笔记29,引用变量(1)
- C++成员变量的初始化顺序问题
- C/C++中常出现的#ifndef,#define,#endif解析
- c++中的引用
- C++学习笔记43——protected访问标识符
- Python: Windows下pip安装库出错:Microsoft Visual C++ 9.0 is required < Unable to find vcvarsall.bat
- c++异常处理
- C++11
- C++ Aggregate 与 POD(Plain Old Data)的解释