Monthly Archives: December 2010

C++ 内存管理及STL 那点事

最近抽了点时间研究下STL,也顺便复习下侯捷的C++内存管理,发现自己基础很薄弱啊,下面把自己这几天看到的,想到的写一下,给那些走在C++学习之路的同学们一点经验和建议,当然本人资质浅薄,可能纰漏百出,还请大家指正。

我在研究STL的时候环境是VS2010,看的书是侯捷的《STL源码剖析》,所以经常出现一些和书上对应不上的情况出现,首先建议大家研究这种库的时候,可以在g++编译环境下,然后按照书中的要求下载一份SGI STL,或者直接使用linux下提供的stl,这样可以免去不一致的麻烦,毕竟我们主要是学习其原理,并不一定要把所有版本的STL研究透彻,微软的STL做的肯定不会比其他的差,但是按照书上一步一步走肯定能少走些路嘛~

首先说下我在VS2010碰到的第一个问题,我们知道STL的vector::iterator 其实应该是一个int型指针,首先萃取器会提取出int的类型,发现时一个int不是指针,所以对应的iterator会变成一个int*。有如下代码:

#include 

#include 

using namespace std;

int main()

{

vector::iterator iter;

cout << sizeof(iter) << endl;

return 0;

}

上述代码在VS2010中,输出为12,显然vs2010在iterator中还加入了其他的东西,在g++中显示的为4,就是一个int型的指针了。上述的例子我还可以举出很多,在STL的学习中,我们一定要记得STL实现的是一个可以为大家方便使用的类库,其表现是相同的,但其内部的原理是不一样的。

还有一个我在初学时碰到的问题:int* list = new int[10];这句话的意思是申请10个int型的空间,调用delete可以归还相应的空间,可是delete方法是怎么知道原先申请了多少的空间呢?如果我们在中途使用delete[] &list[1]会出现什么现象?

如果delete[] &list[1],程序会出错,并且内存泄露,当我们调用new int[10]的时候,其实我们申请了不仅仅10个int空间(40bytes),如下代码可以清晰地解释一下:

#include 

using namespace std;

int main()

{

void* vp;

int* l = new int[6];

for(int i = 0;i < 6;i ++)

{

l[i] = i;

}

vp = (void*) &l[0];

char* c = (char*) vp;

for(int i = -28;i < 36;i ++)

{

cout << i << ": " << (int) c[i] << endl;

}

delete[] l;

return 0;

}

结果显示为:

-28: 0

-27: 46

-26: 91

-25: 0

-24: 0

-23: 0

-22: 0

-21: 0

-20: 0

-19: 0

-18: 0

-17: 0

-16: 24

-15: 0

-14: 0

-13: 0

-12: 1

-11: 0

-10: 0

-9: 0

-8: 126

-7: 0

-6: 0

-5: 0

-4: -3

-3: -3

-2: -3

-1: -3

0: 0

1: 0

2: 0

3: 0

4: 1

5: 0

6: 0

7: 0

8: 2

9: 0

10: 0

11: 0

12: 3

13: 0

14: 0

15: 0

16: 4

17: 0

18: 0

19: 0

20: 5

21: 0

22: 0

23: 0

24: -3

25: -3

26: -3

27: -3

28: 0

29: 0

30: 0

31: 0

32: -65

33: -52

34: 82

35: 100
其中-28 到-25、32到35为随机显示,未知数,其他在vs2010中显示的应该都一样,根据大量数据的检测,结果相同,所以可以猜测,-16到-13表示的是数组的大小bytes,其他应该是数组的边界特殊表示符。
根据侯捷的C++内存管理,我们知道,其实new在底层是调用的malloc,c++内存池保管着几个内存链,所以C++ 在new 一个数组的时候,前端是有cookie表示数组的大小(后端我记得也有,好像是取整的一段吧,就是8, 14, 32……等有cookie)delete调用的时候,根据cookie来归还给内存池,调用new方法的时候,根据大小再适当分配。
以上测验在VS2010上通过,数据表示方法在g++中是不一样的,内存泄露是c/c++程序员不可躲避的一个问题,理解了底层的原理能够更好的帮助我们了解和更好的工作。
参考资料:
《STL源码剖析》
《C++内存管理》

原创文章,转载请注明: 转载自yongxiu

本文链接地址: https://yongxiu.net/201012/1497.html