高质量C++/C编程学习笔记(三)----- 内存管理(1)_C/C++_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > C/C++ > 高质量C++/C编程学习笔记(三)----- 内存管理(1)

高质量C++/C编程学习笔记(三)----- 内存管理(1)

 2010/11/19 9:18:48  lingyibin  http://lingyibin.javaeye.com  我要评论(0)
  • 摘要:1、三种内存分配方式这是最基本的知识。(1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。(3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存
  • 标签:C++/C编程学习笔记 内存管理

1、 三种内存分配方式?

这是最基本的知识。

(1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的 整个运行期间都存在。例如全局变量,static 变量。 (2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函 数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 (3) 从堆上分配,亦称动态内存分配。程序在运行的时候用 malloc 或 new 申请任意多 少的内存,程序员自己负责在何时用 free 或 delete 释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多

?

2、易错点

(1)?内存分配未成功,却使用了它。

应在使用前先检查是否为NULL, 如果在函数中则可用assert来判断:assert(p != NULL);

(2)?内存分配虽然成功,但是尚未初始化就引用它。

(3)?内存分配成功并且已经初始化,但操作越过了内存的边界。最常见的就是数组。

(4)?忘记了释放内存,造成内存泄露。

动态内存的申请与释放必须配对, malloc后记得 free,new后记得delete。

(5)?释放了内存却继续使用它。比较难发现的一个错误是用return返回指向“栈内存”的“指针”或者“引用” ,但该内存在函数体结束时就被自动销毁了。

(6)使用 free 或 delete 释放了内存后,要将指针设置为 NULL,否则会导致产生“野指针”

(7)不要忘记为数组和动态内存赋初值,防止将未被初始化的内存作为右值使用。

?

3、指针与数组

很多人都认为指针和数组是等价的,其实不然。

数组?要么在静态存储区被创建 (如全局数组) , 要么在栈上被创建。 数组名对应着 (而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。 指针?可以随时指向任意类型的内存块,它的特征是“可变” ,所以我们常用指针来操作动态内存。指针远比数组灵活,但也更危险

?

?

char a[] = “hello”; 
a[0] = ‘X’; 
cout << a << endl; 
char *p = “world”;     //  注意 p 指向常量字符串 
p[0] = ‘X’;            //  编译器不能发现该错误 
cout << p << endl; 

从上面这个例子可以看出, 指针 p 指向常量字符串“world” (位于静态存储区,内容为 world\0) ,常量字符串的内容是不可以被修改的。?

注意,不能把数组a的内容用b=a的方式赋值给数组b,因为这会产生编译错误。应该用strcpy 进行复制。

而if(p==a) ?比较的不是内容而是地址,应该用库函数 strcmp来进行比较。

下面是它与指针在这些方面的差别。

?

 //  数组… 
 char a[] = "hello"; 
 char b[10]; 
 strcpy(b, a);   //  不能用 b = a; 
 if(strcmp(b, a) == 0) //  不能用  if (b == a) 
… 
 //  指针… 
 int len = strlen(a); 
 char *p = (char *)malloc(sizeof(char)*(len+1)); 
 strcpy(p,a);   //  不要用 p = a; 
 if(strcmp(p, a) == 0) //  不要用 if (p == a) 
… 

?

?4、计算内存容量。

这一点在面试时可以考倒一大堆人。

sizeof 可以计算出数组的容量(字节数),包括'\0'。如果参数是一个指针的话,那么返回的是指针的长度:4 。。 C++/C语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。

还有一点:当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。看几个例子:

?

 char a[] = "hello world"; 
 char *p  = a; 
 cout<< sizeof(a) << endl; // 12 字节 
 cout<< sizeof(p) << endl; // 4 字节 
 void Func(char a[100]) 
 { 
  cout<< sizeof(a) << endl; // 4 字节而不是 100 字节 
} 
?

?

?

发表评论
用户名: 匿名