变量及内存分配
来源:互联网 发布:数据库管理员前景 编辑:程序博客网 时间:2024/06/05 03:15
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放
4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码。
一个正常的程序在内存中通常分为程序段,数据端和堆栈三部分。程序段里放着程序的机器码和只读数据,这个段通常是只读,对它的写操作是非法的。数据段放的是程序中的静态数据。动态数据则通过堆栈来存放。在内存中,它们的位置如下:
+------------------+ 内存低端
| 程序段 |
|------------------|
| 数据段 |
|------------------|
| 堆栈 |
+------------------+ 内存高端
全局变量、静态数据、常量存放在全局数据区,所有函数的代码存放在代码区,为运行函数而分配的局部变量、函数参数、返回数据、返回地址等存放在栈区。
内存分配方式有三种:
[1]从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
[2]在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
[3]从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释 放内存。动态内存的生存期由程序员决定,使用非常灵活,但如果在堆上分配了空间,就有责任回收它,否则运行的程序会出现内存泄漏,频繁地分配和释放不同大 小的堆空间将会产生堆内碎块。
- //main.cpp
- int a = 0; 全局初始化区
- char *p1; 全局未初始化区
- main()
- {
- int b;// 栈
- char s[] = "abc"; //栈
- char *p2; //栈
- char *p3 = "123456"; //"123456/0"在常量区,p3在栈上。
- static int c =0; //全局(静态)初始化区
- p1 = (char *)malloc(10);
- p2 = (char *)malloc(20);
- //分配得来得10和20字节的区域就在堆区。
- strcpy(p1, "123456"); //123456/0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
- }
【规则1】用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存。
【规则2】不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。
【规则3】避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作。
【规则4】动态内存的申请与释放必须配对,防止内存泄漏。
【规则5】用free或delete释放了内存之后,立即将指针设置为NULL,防止产生“野指针”。
指针与数组的对比
C++/C程序中,指针和数组在不少地方可以相互替换着用,让人产生一种错觉,以为两者是等价的。
数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。
指针可以随时指向任意类型的内存块,它的特征是“可变”,所以我们常用指针来操作动态内存。指针远比数组灵活,但也更危险。
下面以字符串为例比较指针与数组的特性。
1 修改内容
下例中,字符数组a的容量是6个字符,其内容为hello。a的内容可以改变,如a[0]= 'x'。指针p指向常量字符串"world"(位于静态存储区,内容为world),常量字符串的内容是不可以被修改的。从语法上看,编译器并不觉得语句 p[0]= 'x'有什么不妥,但是该语句企图修改常量字符串的内容而导致运行错误。
void main()
{
char a[] = "hello";
a[0] = 'x';
cout << a << endl;
char *p = "world"; // 注意p指向常量字符串
p[0] = 'x'; // 编译器不能发现该错误
cout << p << endl;
}
2 内容复制与比较
不能对数组名进行直接复制与比较。下例中,若想把数组a的内容复制给数组b,不能用语句 b = a ,否则将产生编译错误。应该用标准库函数strcpy进行复制。同理,比较b和a的内容是否相同,不能用if(b==a) 来判断,应该用标准库函数strcmp进行比较。
语句p = a 并不能把a的内容复制指针p,而是把a的地址赋给了p。要想复制a的内容,可以先用库函数malloc为p申请一块容量为strlen(a)+1个字符的内存,再用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)
…
3 计算内存容量
用运算符sizeof可以计算出数组的容量(字节数)。下例(a)中,sizeof(a)的值是12(注意别忘了' ')。指针p指向a,但是 sizeof(p)的值却是4。这是因为sizeof(p)得到的是一个指针变量的字节数,相当于sizeof(char*),而不是p所指的内存容量。 C++/C语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。下例(b)中,不论数组a的容量是多少,sizeof(a)始终等于sizeof(char *)。
示例(a)char *p = a;
cout<< sizeof(a) << endl; // 12字节
cout<< sizeof(p) << endl; // 4字节
示例(b)
{
cout<< sizeof(a) << endl; // 4字节而不是100字节
}
- 变量及内存分配
- JAVA变量及内存分配
- JAVA变量及内存分配
- C语言变量声明及内存分配
- Java--内存分配及变量存储位置
- C语言变量声明及内存分配
- 指针做形参做局部变量及内存分配
- 内存分配及(静态)全局(局部)变量
- java 内存分配及变量存储位置
- java内存分配及变量存储
- 内存分配方式及变量存在地点
- 【Java内存】Java--内存分配及变量存储位置
- 变量的内存分配
- 变量内存的分配
- 变量内存分配
- 变量内存分配
- 变量的内存分配
- 变量内存分配
- 自己可能用到的笔试面试题(整理C/C++)
- 使用chmod同时给目录、文件夹赋予不同的权限
- 微信公众账号运营培训内部教程
- PLSQL常用语句汇总
- 直接拿来用!最火的iOS开源项目(二)
- 变量及内存分配
- strcat实现
- YII Framework学习教程-用YIIC快速创建YII应用之三
- vpn的设置方法(windows 8)
- 升级ADT报错,Working copy not locked; this is probably a bug, please report
- 博客 2
- JAVA经典算法40例
- LEADTOOLS HTML5 SDK使用教程:DICOM图像注释
- ECMA167 - Volume数据结构