《C语言教程》13章 为指针动态分配内存

[复制链接]
912|7
 楼主| niuyaliang 发表于 2015-3-17 20:18 | 显示全部楼层 |阅读模式
C语言程序员要严防内存泄漏,这个“内存泄漏”就是由动态内存分配引起的。指针是C语言和其它语言的最大区别,也是很多人不能跨入C语言的一道门槛。既然指针是这么一个“危险”的坏东西,干吗不取消它呢?
 楼主| niuyaliang 发表于 2015-3-17 20:18 | 显示全部楼层
其实指针本身并没有好坏,它只是一种操作地址的方法,学会了便可以发挥其它语言难以匹敌的功能,没学会的话,只能做其它语言的程序员,也同样发挥你的光和热。小雅本人也在C语言门外徘徊多年,至今仍属于初学者。
 楼主| niuyaliang 发表于 2015-3-17 20:19 | 显示全部楼层
一、变量和数组可以通过指针来转换
“int *x”中的x究竟是不是数组?光看这一句小雅无法告诉你,因为它既可表示单个变量内容,也可表示数组。下面是小雅专门为你准备的例子,理解之后,对动态分配时长度计算有好处。

  1. #include <stdio.h>

  2. int main(void)
  3. {
  4.     int *num = NULL;
  5.     int *x, y[] = {12, 22,32}, z = 100;

  6.     //下面演示,指针既可充当变量、也可充当数组
  7.     x=&z;      //整型变量的地址赋给x
  8.     printf("*x=%d, x[0]=%d\n", *x, x[0]);

  9.     x = y;     //数组的地址赋给x
  10.     printf("*x=%d, x[ 0]=%d, x[ 1]=%d, x[2]=%d\n", *x, x[0], x[1], x[2]);

  11.     x = y + 1; //数组的第二位地址赋给x
  12.     printf("*x=%d, x[-1]=%d, x[ 0]=%d, x[1]=%d\n", *x, x[-1], x[0], x[1]);

  13.     x = y + 2; //数组的第三位地址赋给x
  14.     printf("*x=%d, x[-2]=%d, x[-1]=%d, x[0]=%d\n", *x, x[-2], x[-1], x[0]);

  15.     return 0;
  16. }

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| niuyaliang 发表于 2015-3-17 20:20 | 显示全部楼层
二、动态分配内存
前面讲到的指针,基本上将已经定义好的变量的地址赋给指针变量,现在要学的是向操作系统申请一块新的内存。申请到的内存,必须在某个地方手动释放,因此下面2个函数必须配对使用。malloc()和free(),都是标准函数,在stdlib.h中定义。
根据不同的电脑使用状况,申请内存有可能失败,失败时返回NULL,因此,动态申请内存时,一定要判断结果是否为空。malloc()的返回值类型是“void *”,因此,不要忘记类型转换。(许多人都省略了。)

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. int main(void)
  5. {
  6.     char *p ;

  7.     p = (char *)malloc(40 * sizeof(char)) ;
  8.     if (p == NULL) {          //这个判断是必须的
  9.         printf("内存分配出错!");
  10.         exit(1);
  11.     }
  12.     strcpy(p, "这是劝学网C语言教程。\n");   //不要忘记给新内存赋值
  13.     printf("%s", p);

  14.     free(p);    //过河一定要拆桥
  15.     p = NULL ;  //释放后的指针置空,这是非常好的习惯,防止野指针。

  16. return 0;
  17. }

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| niuyaliang 发表于 2015-3-17 20:20 | 显示全部楼层
三、隐蔽的内存泄漏
内存泄漏主要有以下几种情况:
内存分配未成功,却使用了它。
内存分配虽然成功,但是尚未初始化就引用它。
内存分配成功并且已经初始化,但操作越过了内存的边界。
忘记了释放内存,造成内存泄露。
释放了内存却继续使用它。
 楼主| niuyaliang 发表于 2015-3-17 20:21 | 显示全部楼层
下面的程序造成内存泄漏,想想错在何处?如何修改?
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int main(void)
  4. {
  5.     int *p, i;

  6.     p = (int *)malloc(6 * sizeof(int)) ;
  7.     if (p == NULL) {    //判断是否为空
  8.         printf("内存分配出错!");
  9.         exit(1);
  10.     }

  11.     for (i=0; i<6; i++) {
  12.         p++;
  13.         *p = i;
  14.         printf("%2d", *p);
  15.     }
  16.     printf("\n");

  17.     free(p);    //这句运行时出错

  18.     return 0;
  19. }


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| niuyaliang 发表于 2015-3-17 20:21 | 显示全部楼层
四、对动态内存的错误观念
有人对某一只在函数内使用的指针动态分配了内存,用完后不释放。其理由是:函数运行结束后,函数内的所有变量全部消亡。这是错误的。动态分配的内存是在“堆”里定义,并不随函数结束而消亡。
 楼主| niuyaliang 发表于 2015-3-17 20:22 | 显示全部楼层
有人对某动态分配了内存的指针,用完后直接设置为NULL。其理由是:已经为NULL了,这就释放了。这也是错误的。指针可以任意赋值,而内存并没有释放;相反,内存释放后,指针也并不为NULL。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

212

主题

2427

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部