C++入门(3)——使用new分配内存

指针和数字

指针不是整型,虽然计算机通常把地址当作整数处理。指针描述的是位置,对两个地址相乘并没有意义。因此,不能简单地将整数赋给指针

使用new来分配内存

对指针有一定了解之后,我们来看看它如何实现在程序运行时分配内存。前面我们将指针初始为变量地址只是为了描述指针的作用,而变量是在编译时分配的有名称的内存。指针真正的用处在于,在运行阶段分配未命名的内存来储存值。在C语言中,可以使用库函数malloc() 来分配内存,在C++中仍然可以这么做,但有更好的方法new

   int *a = new int;

new int告诉程序,需要适合存储int的内存。new运算符根据类型来确定需要多少字节的内存。然后它找到这样的内存,并返回其地址,将地址赋给a,a是被声明指向int的指针,现在*a是存储在那里的值。我们来看一下具体应用

   #include <iostream>
    int main()
    {
        using namespace std;
        int nights = 1001;
        int * pt = new int;  // allocate space for an int
        *pt = 1001;    // store a value there
        cout << "nights value = ";
        cout << nights << ":location = " << &nights << endl;
        cout << "int values = " << *pt << ": location = " << pt << endl;
        double * pd = new double;  // allocate space for a double
        *pd = 100001.0;   // store a double there
        cout << "double value = " << *pd << ":location = " << pd << endl;
        cout << "location of pointer pd: " << &pd << endl;
        cout << "size of pt = " << sizeof(pt);
        cout << ":size of *pt = " << sizeof(*pt) << endl;
        cout << "size of pd = " << sizeof(pd);
        cout << "size of *pd = " << sizeof(*pd) << endl;
        return 0;
    }

结果如下

    nights value = 1001:location = 0x7ffdd5606704
    int values = 1001: location = 0x1034c20
    double value = 100001:location = 0x1035050
    location of pointer pd: 0x7ffdd5606708
    size of pt = 8:size of *pt = 4
    size of pd = 8size of *pd = 8

从中可以看到,虽然变量night 和指针*pt 指向的变量值相同,但一个是编译时由系统分配的地址,另一个是我们通过 new 由系统分配的地址。而且我们发现,对于指针pd,我们还可以对它再求地址,就得到这个指针变量的地址。(可以理解为指针管理了一个变量的两个方面——地址和值,而指针自己也有在内存中的存储地址)

使用delete释放内存

当需要内存时,可以使用new来请求,这只是C++内存管理数据包中有魅力的一方面。另一方面是delete 运算符在使用完内存后将其释放给内存池(而不是其他语言的垃圾回收)

   int *ps = new int; //allocate memory with new
   delete ps;    // free memory with delete when done

这将释放ps指向的内存,但不会删除指针ps本身,例如可以将ps重新指向另一个新分配的内存块。一定要配对地使用newdelete ,否则将发生内存泄漏(memory leak)。也就是说,被分配的内存再也无法使用了。

使用new来创建动态数组

如果程序只需要一个值,则可能会声明一个简单变量,但对于大型数据(如数组,字符串和结构),应使用new。假如一个程序,它是否需要数组取决于运行时用户提供的信息。如果通过声明来创建数组,则在程序被编译时将为它分配内存空间。不管程序最终是否使用数组,数组都在那里,它浪费了内存。
下面来看一下使用new创建动态数组

   int *arr = new int [10] // get a block of 10 ints
   delete [] arr;  // 方括号代表释放整个数组

new运算符返回第一个元素的地址,在这个例子中,该地址被赋给指针arr。那么如何访问其中的元素呢?第一个元素不成问题,由于arr指向数组的第一个元素,还有9个元素,只需要把指针当作数组名使用就可以,arr[0] 是第一个元素,以此类推。(这里不需要*号)

    #include <iostream>
    int main()
    {
        using namespace std;
        double *p3 = new double[3];
        p3[0] = 0.2;    // space for 3 doubles
        p3[1] = 0.5;    // treat p3 like an Array name
        p3[2] = 0.8;
        cout << "p3[1] is " << p3[1] << ".\n";
        p3 = p3 + 1;
        cout << "Now p3[0] is " << p3[0] << " and ";
        cout << "p3[1] is " << p3[1] << ".\n";
        p3 = p3 - 1;     // point back to beginning
        delete []p3;    // free the memory
        return 0;
    }

我们看一下输出

    p3[1] is 0.5.
    Now p3[0] is 0.5 and p3[1] is 0.8.

从中可以知道,指针p3 被当作数组名来使用,p3[0] 为第一个元素,依次类推。将p3加1导致它指向第二个元素而不是第一个,将它减1之后,指针指向原来的值,这样程序便可以给delete[]提供正确的地址。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值