Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1336031
  • 博文数量: 284
  • 博客积分: 3251
  • 博客等级: 中校
  • 技术积分: 3046
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-26 17:23
文章分类

全部博文(284)

文章存档

2019年(2)

2018年(5)

2015年(19)

2014年(13)

2013年(10)

2012年(235)

分类: C/C++

2012-08-25 08:04:57

    最近做项目时,对malloc和free的用法温习了一下,现在整理如下:
    一、动态分配地址
    malloc函数是动态分配空间,free函数把malloc等动态分配空间释放掉。所以,malloc申请的空间,不能静态赋值。例如下面的代码是错误的:

  1. #include<stdlib.h>
  2. void main()
  3. {
  4.  char *test=malloc(100);
  5.  test="123";
  6.  free(test);
  7.  test=NULL;
  8. }
    *test=malloc(100);只是把申请好的空间首地址赋给test,也就是test指向空间首地址,而test="123";是吧字符串“123”的首地址赋给了test,也就是说,赋值后,test从指向malloc申请的空间首地址改成了指向字符串首地址,变成了静态地址空间,free(test);自然而然会出错误。

    二、申请空间大小问题

  1. (1)
  2. char *p = (char*)malloc(sizeof(char));
  3.  strcpy(p,"hello");
  4.  cout<<p<<endl;

  5. (2)
  6.  char *p = (char*)malloc(sizeof(char)*100);
  7.  strcpy(p,"hello");
  8.  cout<<p<<endl;
  9.  free(p);
    上面两个例子,区别在于malloc动态分配空间大小不一样,(1)中分配了sizeof(char)大小的空间,(2)中分配了sizeof(char)*100;的空间,后面都是把“hello”赋值给p指针指向的空间,可以看到赋值大小为5个字符,显然(1)是不够的,这里(2)是对的,当然,在程序实际运行过程中,(1)有可能不会提示内存错误,因为溢出的空间有可能刚好是空闲的,所以,这里要特别注意。
   
    三、如何给动态空间赋值
    这里以字符串赋值为例:
   
char *p = (char*)malloc(sizeof(char)*100);
    我们申请了100个字节的动态空间,p指针指向其首地址。这里不能用

    p=
"hello";
    这种方式赋值,原因在一中说过了。而应该按p++这种动态地址指向赋值,想把一个字符串赋值过来,要用

  
  strcpy(p,"hello");
    看strcpy()函数原型,可以发现,该函数是按照数组元素来逐个赋值的,与下面的例子代码类似:

  1. amovep(int *p,int(*a)[3],int n)
  2. {
  3. int i,j;
  4. for(i=0;i<n;i++)
  5. for(j=0;j<n;j++)
  6. {
  7.      *p=a[i][j];
  8.      p++;
  9. }
  10. main()
  11. {
  12.      int *p,a[3][3]={{1,2,3},{4,5,6}};
  13.      p=(int*)malloc(sizeof(int)*100);
  14.      amovep(p,a,3);
  15.      printf("%d%d\n",p[2],p[5]);
  16.      free(p);
  17. }
    四、函数的用法规范

  1. // Code...

  2. char *Ptr = NULL;
  3. Ptr = (char *)malloc(100 * sizeof(char));
  4. if (NULL == Ptr)
  5. {
  6.     exit (1);
  7. }
  8. gets(Ptr);

  9. // code...

  10. free(Ptr);
  11. Ptr = NULL;

  12. // code...
     关于函数使用需要注意的一些地方:
     1、申请了内存空间后,必须检查是否分配成功。
     2、当不需要再使用申请的内存时,记得释放;释放后应该把指向这块内存的指针指向NULL,防止程序后面不小心使用了它。
     3、这两个函数应该是配对。如果申请后不释放就是内存泄露;如果无故释放那就是什么也没有做。释放只能一次,如果释放两次及两次以上会出现错误(释放空指针例外,释放空指针其实也等于啥也没做,所以释放空指针释放多少次都没有问题)。
     4、虽然malloc()函数的类型是(void *),任何类型的指针都可以转换成(void *),但是最好还是在前面进行强制类型转换,因为这样可以躲过一些编译器的检查。



阅读(3831) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~