码迷,mamicode.com
首页 > 其他好文 > 详细

C和指针

时间:2015-06-01 16:07:36      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:

Chapter.11 动态内存分配
    由于数组在使用上的时候,数组声明之后大小就不能再调整,所需的内存在编译时就会被分配。但是如果使用动态内存分配的话就可以使用可变化长度的数组。
    数组静态分配的缺点:
  1. 在程序中引入了人为的限制。
  2. 一旦声明的过大或导致空间的浪费。
  3. 当输入输出超出容纳范围时程序必须以合理的方式进行响应。
malloc、free、calloc和realloc:
    这几个函数都是在<stdlib.h>头文件中声明的,函数原型如下:
    void *malloc(size_t size);
    void free(void* pointer);    
    void *calloc(size_t num_elements,size_t element_size);
    void realloc(void *ptr,size_t new_size);
    malloc分配的内存是连续的一块内存,同时实际分配出来的大小应该是根据编译器具体而定的。特别要注意的是malloc可能会分配失败,因为系统的内存池中可能没有足够的内存进行分配这时malloc返回的就是一个NULL指针。因此特别有必要对每一个malloc返回的指针都要进行检查!malloc函数的返回值实际是一个void*类型的空指针,可以由强制类型转换成我们需要的指针类型。向free函数传递的参数必须是上述其他三个函数返回的指针或者是空指针NULL。calloc函数的不同之处有两个:一是会对分配的内存进行初始化为全0;二是请求内存的方式不一样,这一点在两个函数的参数上就可以看出来。relloc函数用来修改一个原先已经分配的内存的大小,当第一个参数是NULL的时候,实际效果和malloc是一样的。如果原先的内存块无法改变大小(例如说已经声明的数组???)那么会申请一块新的正确大小的内存,然后将原来的内容复制到新块上。
    常见的动态内存分配的错误:
  1. 对空指针进行解引用操作。
  2. 对分配的内存进行访问时越界。
  3. 试图释放并非动态分配的内存。
  4. 试图释放动态分配的内存的一部分。
  5. 一块内存释放之后仍然试图访问。
下面的代码定义了一个不易发生错误的内存分配器(因为内存分配最大的错误就是内存分配失败返回空指针而没有检查。)
  1. /*
  2. How to define a memory allocator which is not that easily to make mistakes
  3. */
  4. #include <stlib.h>
  5. #define malloc Don`t call malloc directly
  6. #define MALLOC(num,type) (type *)alloc((num)*sizeof(type))
  7. extern void *alloc(size_t size)
  8. /***************************************************************/
  9. /*The implement of the allocator*/
  10. #include <stdio.h>
  11. #include "alloc.h"
  12. #undef malloc
  13. void *alloc(size_t size){
  14. void *new_mem;
  15. new_men=malloc(size);
  16. if(new_mem==NULL){
  17. printf("out of memory\n");
  18. exit(1);
  19. }
  20. return new_mem;
  21. }
  22. /******************************************/
  23. /*an example*/
  24. int *new_mem;
  25. new_men=MALLOC(25,int);
    不要访问已经被free函数释放了的内存,如果说对一个指向动态分配的内存的指针进行了复制操作,而且这个指针的拷贝散布在程序的各个地方那么必要要确保在释放这个指针之前程序里使用这个指针的地方都停止使用这个指针,否则很容易就会出现访问已经释放的内存区域。内存泄露就是说没有释放动态分配的内存导致内存越来越少最终系统死机。使用sizeof来确定分配的内存的大小有助于提高程序的可移植性。

Chapter.14 预处理器
    编译一个C程序的第一个步骤就是 预处理阶段。
    首先看一下#define指令,正式的描述是:#define name stuff,当出现这个指令之后,每当有符号name出现在这条指令之后,预处理器就会把它替换成stuff。替换的文本并不仅仅局限于数值字面常量,可以将任何问题替换到程序中去,例如:
    #define reg register
    #define do_forever for( ; ; )
    #define CASE break;case
如果定义中的stuff比较长那么可以分成几行写,但是每一行的末尾必须用 \ (反斜杠)来进行换行。 










C和指针

标签:

原文地址:http://www.cnblogs.com/hellozlh/p/4543939.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!