标签:
动态内存分配
传统数组的缺点(静态内存分配):
1.数组长度必须事先指定,且只能是常整数,不能是变量
例子:
int a[5]; //OK
int len = 5; int a[len]; //error
2.传统形式定义的数组,该数组的内存程序员无法手动编
程释放,在一个函数运行期间,系统为该函数中数组所
分配的空间会一直存在,直到该函数运行完毕时,数组
元素所占存储空间才会被系统释放
3.数组的长度一旦定义,长度就能被改变
4.A函数定义的数组,在A函数运行期间可以被其它函数使
用,但是当A函数运行结束时,其它函数不能再访问该数
组
1 /* 2 2015年04月26日 09:40:40 3 目的: 4 传统数组的缺点 5 6 */ 7 8 # include <stdio.h> 9 10 void g(int *pArr, int len) 11 { 12 pArr[2] = 88; // pArr[2] == a[2] 13 } 14 15 void f(void) 16 { 17 int a[5] = {1,2,3,4,5}; // 这20个字节的存储空间程序员无法手动编程释放它 18 //它只能在本函数运行完毕时由系统自动释放 19 g(a, 5); 20 printf("%d\n", a[2]); 21 } 22 23 int main(void) 24 { 25 f(); 26 27 return 0; 28 } 29 30 /* 31 在VC6.0中运行结果是: 32 ----------------------------- 33 88 34 ----------------------------- 35 总结: 36 37 */
为什么需要动态内存分配
动态数组很好的解决了传统数组的这4个缺陷
传统数组也叫静态数组
1 /* 2 2015年04月26日 10:15:08 3 目的: 4 malloc 函数的使用 5 malloc 是 memory (内存)allocate (分配)的缩写 6 7 */ 8 9 # include <stdio.h> 10 # include <malloc.h> // 不能省 11 12 int main(void) 13 { 14 int i = 5; //静态分配4个字节 15 int * p = (int *)malloc(4); //第k行 16 /* 17 1.要使用malloc函数,必须添加malloc.h头文件 18 2.malloc函数只有一个形参,并且形参是整型 19 3.malloc(4)中的4表示请求系统为本程序分配4个字节 20 4.malloc函数只能返回第一个字节的地址 21 5.第k行分配了8个字节,p变量占4个字节,p所指向的内存也占4个字节 22 6.p本身所占的内存空间是静态分配,p所指向的内存是动态分配 23 */ 24 *p = 5; //*p和i一样代表整型变量,区别是*p是动态分配 25 free(p); //表示把p所指向的内存单元释放掉,p本身所占用内存空间还存在 26 printf("同志们好!\n"); 27 28 return 0; 29 } 30 31 /* 32 在VC6.0中运行结果是: 33 ----------------------------- 34 同志们好! 35 ----------------------------- 36 总结: 37 38 */
1 /* 2 2015年04月26日 10:40:47 3 目的: 4 malloc 函数的使用 5 malloc 是 memory (内存)allocate (分配)的缩写 6 7 */ 8 9 # include <stdio.h> 10 # include <malloc.h> 11 12 void f(int * q) 13 { 14 //*p = 200; //error,因为p定义在main中 15 //q = 200; //q中只能存放int类型变量的地址 16 /* 17 **q = 200; //error 18 q是指针变量,*q表示指针q所指向 19 的变量,即*q是个变量,不能再加 20 *,只有指针变量前可以加* 21 */ 22 *q = 200; 23 //free(q); //把q所指向的内存释放掉 第k行 24 } 25 26 int main(void) 27 { 28 int * p = (int *)malloc(sizeof(int)); //sizeof(int)返回值是int所占字节数 29 *p = 10; 30 31 printf("%d\n", *p); //10 32 f(p); 33 printf("%d\n", *p); //200 第j行 34 35 return 0; 36 } 37 38 /* 39 在VC6.0中运行结果是: 40 第k行注释掉结果 41 ----------------------------- 42 10 43 200 44 ----------------------------- 45 46 47 在VC6.0中运行结果是: 48 加上第k行的结果 49 ----------------------------- 50 10 51 -572662307 52 ----------------------------- 53 总结:加上第k行会导致第j行输出错误,因为 54 f函数中的结果被释放,导致主函数接收不 55 到数据,只能输出一个垃圾值 56 57 */
动态内存分配_动态数组的构造
1 /* 2 2015年04月26日 11:16:32 3 目的: 4 动态一维数组 5 */ 6 7 # include <stdio.h> 8 # include <malloc.h> 9 10 int main(void) 11 { 12 int len; 13 int * pArr; 14 int i; 15 16 //动态的构造一维数组 17 printf("请输入您要存放的元素的个数:"); 18 scanf("%d", &len); 19 pArr = (int *)malloc(4 * len); 20 /* 21 本行动态构造了一个一维数组,该数组的长度为len, 22 数组名pArr,该数组每个元素是int类型 23 */ 24 25 //对一位数组进行赋值 26 for (i=0; i<len; ++i) 27 scanf("%d", &pArr[i]); 28 29 //输出一维数组内容 30 printf("一维数组的内容是:\n"); 31 for (i=0; i<len; ++i) 32 printf("%d\n", pArr[i]); 33 34 free(pArr); //释放掉动态分配的数组 35 36 return 0; 37 } 38 39 /* 40 在VC6.0中运行结果是: 41 ----------------------------- 42 请输入您要存放的元素的个数:2 43 22 66 44 一维数组的内容是: 45 22 46 66 47 ----------------------------- 48 总结: 49 */
静态内存和动态内存的比较
静态内存是由系统自动分配,由系统释放
静态内存是栈分配
动态内存是由程序员手动分配,手动释放
动态内存是堆分配的
1 /* 2 2015年04月26日 12:48:21 3 目的: 4 多级指针 5 */ 6 7 # include <stdio.h> 8 9 int main(void) 10 { 11 int i = 10; 12 int * p = &i; //&i 是 int * 类型 13 int ** q = &p; //&p 是 int ** 类型 14 int *** r = &q; //&q 是 int *** 类型 15 16 //r = &p; //error 因为r是int *** 类型,r只能存放int ** 类型变量的地址 17 printf("i = %d\n", ***r); 18 19 return 0; 20 } 21 22 /* 23 在VC6.0中运行结果是: 24 ----------------------------- 25 i = 10 26 ----------------------------- 27 总结: 28 *r = q 29 **r = p 30 ***r = i 31 p是指针变量,存放int 类型整型变量i的地址 32 q是指针变量,存放int * 类型指针变量p的地址 33 r是指针变量,存放int ** 类型指针变量q的地址 34 总之,指针变量是用来存放地址 35 36 */
1 /* 2 2015年04月26日 13:01:21 3 目的: 4 跨函数使用多级指针 5 */ 6 7 # include <stdio.h> 8 9 void f(int ** q) 10 { 11 //*q就是p 12 printf("%d\n", **q); 13 } 14 15 void g() 16 { 17 int i = 10; 18 int * p = &i; 19 20 f(&p); //p是int * 类型, &p是int ** 类型 21 } 22 23 int main(void) 24 { 25 g(); 26 27 return 0; 28 } 29 30 /* 31 在VC6.0中运行结果是: 32 ----------------------------- 33 10 34 ----------------------------- 35 总结: 36 37 */
跨函数使用内存的问题
1 /* 2 2015年04月26日 13:32:55 3 目的: 4 跨函数使用内存 5 */ 6 7 # include <stdio.h> 8 9 void f(int ** q) //q是个指针变量,无论q是什么类型的指针变量,都只占4个字节 10 { 11 int i = 5; 12 //*q等价于p , q和**q都不等价于p , p = &i 13 *q = &i; //*q = p 而 p = &i 14 } 15 16 int main(void) 17 { 18 int *p; 19 20 f(&p); 21 printf("%d\n", *p); //本语句语法没错,但逻辑上有问题。第k行 22 23 return 0; 24 } 25 26 /* 27 在VC6.0中运行结果是: 28 ----------------------------- 29 5 30 ----------------------------- 31 总结:本例说明,静态内存分配不能跨函数使用 32 第k行按理说*p是不能输出的,因为f函数里 33 的变量都是静态的,当f函数调用结束,即 34 f(&p);语句执行完时,i已经被系统释放 35 36 37 */
1 /* 2 2015年04月26日 13:57:22 3 目的: 4 动态内存分配的跨函数使用 5 */ 6 7 # include <stdio.h> 8 # include <malloc.h> 9 10 void f(int ** q) 11 { 12 *q = (int *)malloc(sizeof(int)); 13 //sizeof(数据类型) 返回值是该数据类型所占的字节 14 //等价于 p = (int *)malloc(sizeof(int)); 15 **q = 5; 16 } 17 18 int main(void) 19 { 20 int *p; 21 22 f(&p); 23 printf("%d\n", *p); 24 25 return 0; 26 } 27 28 /* 29 在VC6.0中运行结果是: 30 ----------------------------- 31 5 32 ----------------------------- 33 总结:本例说明,动态内存分配能跨函数使用 34 静态内存分配是栈分配 35 动态内存分配是堆分配 36 通常说的堆栈就是指栈,堆是堆 37 38 39 */
标签:
原文地址:http://www.cnblogs.com/houhaibushihai/p/4458585.html