C++内存分配

来源:岁月联盟 编辑:exp 时间:2012-11-01

    自己在处理C++内存分配上的一点心得,如果有错误,欢迎大家指出。
      变量和对象在内存中的分配都是编译器在编译程序时安排好的,但同样带来了不便,如数组必须大开小用,指针必须指向一个已经存在的变量或对象。动态内存分配解决了这个问题。
      C/C++定义了4个内存区间:代码区,全局数据区,栈区,堆区。定义变量是在编译程序的时候就进行的静态存储分配。所有的动态分配都是在堆区进行的。不过是不能说的这么绝对的,与编译器和库都是有关联的。函数的参数未必通过堆栈进行分配,这与具体的编译器都是有关的。而对于内存分配失败时的返回值也不一定为NULL,很多的编译器都可以捕获new操作符抛出的异常。

      全局数据区     代码区     栈区          堆区
      data                code       stack          heap

      全局变量         函数      局部变量     new,delete申请的空间
      静态数据                      函数参数    
      常量                              返回地址    
                                            返回数据

      堆内存的分配和释放是重复利用有限的资源的关键。

      指针变量名 = new 类型名(初始值);
      delete 指针名;

      new运算符返回的是一个指向所分配类型变量(对象)的指针,而动态创建的对象本身没有标识符名。new表达式会从堆区分配对象,然后用括号中的值初始化改对象。而从堆区分配对象时,new表达式调用库操作符new()。例如:
      int *pi = new int(0);
      注意在内存分配失败的时候,会返回零值,所以要在动态分配内存的时候对返回的指针进行检查。
      当使用delete操作符时,只是释放了指针所指向的内存空间,但指针本身没有撤销,指针所占用的内存空间并没有释放。

      char *pc = new char;
      *pc = 'a';
      int *pi = new int(8);

      栈区     堆区
      pc        a
      pi         8
      但该函数或程序执行完毕后系统弹栈,pc和pi这两个变量将消失,但他们指向的堆区的内存不会自动释放,那么该内存将不能使用,除非系统重启。

      写保护的方法
      char *pc = new char;
      *pc = 'a';
      int *pi = new int(8);

      if (pc)
      {
            delete pc;
      }
      if (pi)
      {
           delete  pi;
      }


      char *string = new char[20];

      if (string == 0)
      {
           return;
      }
      /* ... */
     delete []string;