1. 程式人生 > >C++之 new 動態分配記憶體

C++之 new 動態分配記憶體

動態記憶體分配
1.堆記憶體分配 :
C/C++定義了4個記憶體區間:程式碼區,全域性變數與靜態變數區,區域性變數區即棧區,動態儲存區,即堆(heap)區或自由儲存區(free store)。

堆的概念:
通常定義變數(或物件),編譯器在編譯時都可以根據該變數(或物件)的型別知道所需記憶體空間的大小,從而系統在適當的時候為他們分配確定的儲存空間。這種記憶體分配稱為靜態儲存分配;
有些操作物件只在程式執行時才能確定,這樣編譯時就無法為他們預定儲存空間,只能在程式執行時,系統根據執行時的要求進行記憶體分配,這種方法稱為動態儲存分配。所有動態儲存分配都在堆區中進行。
當程式執行到需要一個動態分配的變數或物件時,必須向系統申請取得堆中的一塊所需大小的存貯空間,用於存貯該變數或物件。當不再使用該變數或物件時,也就是它的生命結束時,要顯式釋放它所佔用的存貯空間,這樣系統就能對該堆空間進行再次分配,做到重複使用有限的資源。

2.堆記憶體的分配與釋放
堆空間申請、釋放的方法:
在C++中,申請和釋放堆中分配的存貯空間,分別使用new和delete的兩個運算子來完成:    
指標變數名=new 型別名(初始化式);
    delete 指標名;
例如:
1、 int *pi=new int(0);
它與下列程式碼序列大體等價:
2、int ival=0, *pi=&ival;

區別:pi所指向的變數是由庫操作符new()分配的,位於程式的堆區中,並且該物件未命名。  

堆空間申請、釋放說明:
⑴.new運算子返回的是一個指向所分配型別變數(物件)的指標。對所建立的變數或物件,都是通過該指標來間接操作的,而且動態建立的物件本身沒有名字。
⑵.一般定義變數和物件時要用識別符號命名,稱命名物件,而動態的稱無名物件(請注意與棧區中的臨時物件的區別,兩者完全不同:生命期不同,操作方法不同,臨時變數對程式設計師是透明的)。
⑶.堆區是不會在分配時做自動初始化的(包括清零),所以必須用初始化式(initializer)來顯式初始化。new表示式的操作序列如下:從堆區分配物件,然後用括號中的值初始化該物件。

3.堆空間申請、釋放演示:
⑴.用初始化式(initializer)來顯式初始化 
int *pi=new int(0);
⑵.當pi生命週期結束時,必須釋放pi所指向的目標:
delete pi;

注意這時釋放了pi所指的目標的記憶體空間,也就是撤銷了該目標,稱動態記憶體釋放(dynamic memory deallocation),但指標pi本身並沒有撤銷,它自己仍然存在,該指標所佔記憶體空間並未釋放。 

下面是關於new 操作的說明 
⑴.new運算子返回的是一個指向所分配型別變數(物件)的指標。對所建立的變數或物件,都是通過該指標來間接操作的,而動態建立的物件本身沒有名字。 
⑵.一般定義變數和物件時要用識別符號命名,稱命名物件,而動態的稱無名物件(請注意與棧區中的臨時物件的區別,兩者完全不同:生命期不同,操作方法不同,臨時變數對程式設計師是透明的)。 
⑶.堆區是不會在分配時做自動初始化的(包括清零),所以必須用初始化式(initializer)來顯式初始化。new表示式的操作序列如下:從堆區分配物件,然後用括號中的值初始化該物件。

4. 在堆中建立動態一維陣列
①申請陣列空間:
指標變數名=new 型別名[下標表達式];
注意:“下標表達式”不是常量表達式,即它的值不必在編譯時確定,可以在執行時確定。

②釋放陣列空間:
delete [ ]指向該陣列的指標變數名;

注意:方括號非常重要的,如果delete語句中少了方括號,因編譯器認為該指標是指向陣列第一個元素的,會產生回收不徹底的問題(只回收了第一個元素所佔空間),加了方括號後就轉化為指向陣列的指標,回收整個陣列。delete [ ]的方括號中不需要填陣列元素數,系統自知。即使寫了,編譯器也忽略。
#include <iostream.h>
#include <string.h>
void main(){
     int n;
     char *pc;
     cout<<"請輸入動態陣列的元素個數"<<endl;
     cin>>n; //n在執行時確定,可輸入17
     pc=new char[n]; //申請17個字元(可裝8個漢字和一個結束符)的記憶體空間
     strcpy(pc,“堆記憶體的動態分配”);//
     cout<<pc<<endl;
     delete []pc;//釋放pc所指向的n個字元的記憶體空間
     return ;
}


5. 動態一維陣列的說明
① 變數n在編譯時沒有確定的值,而是在執行中輸入,按執行時所需分配堆空間,這一點是動態分配的優點,可克服陣列“大開小用”的弊端,在表、排序與查詢中的演算法,若用動態陣列,通用性更佳。一定注意:delete []pc是將n個字元的空間釋放,而用delete pc則只釋放了一個字元的空間;
② 如果有一個char *pc1,令pc1=p,同樣可用delete [] pc1來釋放該空間。儘管C++不對陣列作邊界檢查,但在堆空間分配時,對陣列分配空間大小是紀錄在案的。
③ 沒有初始化式(initializer),不可對陣列初始化。 

6.指標陣列和陣列指標
指標型別:
(1)int*ptr;//指標所指向的型別是int 
(2)char*ptr;//指標所指向的的型別是char 
(3)int**ptr;//指標所指向的的型別是int* (也就是一個int * 型指標) 
(4)int(*ptr)[3];//指標所指向的的型別是int()[3] //二維指標的宣告

指標陣列:
一個數組裡存放的都是同一個型別的指標,通常我們把他叫做指標陣列。 
比如 int * a[2];它裡邊放了2個int * 型變數 .
int * a[2]; 
a[0]= new int[3]; 
a[1]=new int[3]; 
delete a[0]; 
delete a[1]; 
注意這裡 是一個數組,不能delete [] ; 

陣列指標:
一個指向一維或者多維陣列的指標.
int * b=new int[10]; 指向一維陣列的指標b ; 
注意,這個時候釋放空間一定要delete [] ,否則會造成記憶體洩露, b 就成為了空懸指標 

int (*b2)[10]=new int[10][10]; 注意,這裡的b2指向了一個二維int型陣列的首地址. 
注意:在這裡,b2等效於二維陣列名,但沒有指出其邊界,即最高維的元素數量,但是它的最低維數的元素數量必須要指定!就像指向字元的指標,即等效一個字串,不要把指向字元的指標說成指向字串的指標。
int(*b3) [30] [20]; //三級指標――>指向三維陣列的指標; 
int(*b2) [20];     //二級指標;――>指向二維陣列的指標; 
b3=new int [1] [20] [30]; 
b2=new int [30] [20]; 
刪除這兩個動態陣列可用下式: 
delete [] b3; //刪除(釋放)三維陣列; 
delete [] b2; //刪除(釋放)二維陣列;

在堆中建立動態多維陣列
new 型別名[下標表達式1] [下標表達式2]……;

例如:建立一個動態三維陣列
float (*cp)[30][20] ; //指向一個30行20列陣列的指標,指向二維陣列的指標
cp=new float [15] [30] [20]; //建立由15個30*20陣列組成的陣列;

注意:cp等效於三維陣列名,但沒有指出其邊界,即最高維的元素數量,就像指向字元的指標即等效一個字串,不要把指向字元的指標,說成指向字串的指標。這與陣列的巢狀定義相一致。

附:new和delete用法

在記憶體管理上,C++ 和 C 有著完全不同的兩套方案。當然,C++的總是同時相容C。C的那一套方案在C++裡同樣可行。

      new ,從字面上看意思為 “新”;而delete 字面意思為“刪除”。二者在C++中記憶體管理中大致的功能,應是一個為“新建”,一個為“刪除”。

一、new 

      new 是 c++ 的一個關鍵字。被當作像 +、-、* 、/ 一樣的操作符。它的操作結果是在申請到一段指定資料型別大小的記憶體。

  語法: 指標變數 = new 資料型別;

     new 將做三件事:

  1、主動計算指定資料型別需要的記憶體空間大小;

     2、返回正確的指標型別;

    3、在分配記憶體的一,將按照語法規則,初始化所分配的記憶體。

  這是什麼意思呢?看看例子吧:

  int* p;

     p = new int;

  和以往不一樣,p 這回不再“寄人籬下”,並不是指向某個已存在的變數,而是直接指向一段由new 分配而來的新記憶體空間。

  “p 指向一段由new 分配而來的新記憶體空間” 這句話等同於: “new 分配一段新的記憶體空間,然後將該記憶體空間的地址存入到變數p中。” 所以,最終p中仍然是儲存了一個變數的地址,只是,這是一個“無名”變數。

  指向原有的某個變數,和指向一段新分配的記憶體空間,有什麼區別呢?

      “原有的變數”,可以比喻成指向一間原有的,並且有主的房間。而“新分配的記憶體空間”,則像是一個“臨時建築物”。我們必須在不用它的時候,主動將它拆遷。拆遷的工作由delete來完成。

  當指標變數通過 new ,而得到一個記憶體地址後,我們就可以像以前的所說的,通過該指標,通過*號,而對該記憶體地址(一個無名的變數),進行操作。

     如:

     int* p = new int;

     *p = 100;

     cout << *p << endl;

  螢幕將輸出100。

二、new時初始化 

     new 也可以在申請記憶體空間時,直接設定該段記憶體裡要放點什麼.

  語法: 指標變數 = new 資料型別(初值);

三、delete

     語法: delete 指標變數;

  delete 將釋放指定指標所指向的記憶體空間。  

     注意,當一個指標接受delete操作後,它就又成了一個“指向不明”的指標。儘管我們可以猜測它還是指向“原來的房子”,然而,事實上,那座“房子”已經被delete “拆遷”掉了。

四、new[]和delete[]

      new / delete 用於分配和釋放單個變數的空間,而 new [] / delete[] 則用於分配連續多個變數的存間。

    語法: 指標變數 = new 資料型別[元素個數];

     語法:   delete [] 指標變數;

相關推薦

C++ new 動態分配記憶體

動態記憶體分配 1.堆記憶體分配 : C/C++定義了4個記憶體區間:程式碼區,全域性變數與靜態變數區,區域性變數區即棧區,動態儲存區,即堆(heap)區或自由儲存區(free store)。 堆的概念: 通常定義變數(或物件),編譯器在編譯時都可以根據該變數(或物件)的

C++ new動態分配記憶體和delete釋放記憶體

C++中使用簡便而強大的new和delete運算子來進行動態記憶體的分配. 值得注意的是,new和delete和c語言中的malloc和free不同,new和delete是運算子,因此執行效率更高. 如何使用new , delete 呢? 首先我們來看一段程式碼: i

C++new動態分配記憶體生成陣列

#include <iostream> using namespace std; static int b[3][3]; void change(int (*a)[3])//轉置函式 { for(int m=0;m<3;m++) { for(int

c語言獲得動態分配記憶體後的陣列記憶體大小

c語言獲得動態分配記憶體後的陣列記憶體大小 用一個函式 :_msize(); ★注意:該函式為Windows獨有★ int* s = (int*)malloc(sizeof(int));     int i;     for(i

C++動態分配記憶體空間 : new 和 delete

1.什麼是new和delete 在C語言中我們可以利用標準庫函式中的 malloc 和 free 來動態分配記憶體空間,而在C++中提供了運算子 new 和 delete 來取代 malloc 和 f

C++動態分配記憶體(new)和撤銷記憶體(delete)

在軟體開發過程中,常常需要動態地分配和撤銷記憶體空間,例如對動態連結串列中結點的插入與刪除。 在C語言中是利用庫函式malloc和free來分配和撤銷記憶體空間的。 C++提供了較簡便而功能較強的運算子new和delete來取代malloc和free函式。

C語言動態分配記憶體

1. malloc()函式和free()函式 首先,我們應該知道,所有的程式都必須留出足夠的記憶體空間來儲存所使用的資料,所以我們經常會預先給程式開闢好記憶體空間,然後進行操作,但其實還有一種選擇,能夠讓記憶體分配自動進行下去。 對於傳統陣列,會遇到這樣的問

C++操作符new-動態存儲空間分配

c++ 操作 動態 mil bsp ++操作 -s span new c++操作符new可以用來動態存儲分配,我簡單的對new的作用做了簡單的整理。 1.單個字符或整數 1 int *p=new int; 2 *p=10; 3

C儲存類、連結和記憶體管理--動態分配記憶體及型別限定詞

文章目錄 儲存類說明符 儲存類和函式 動態分配記憶體 `malloc`函式 `free`函式 `calloc`函式 動態分配記憶體的缺點 C型別限定關鍵字

c語言動態分配記憶體記憶體分配部分函式

#include<stdio.h> /** 在C中動態分配記憶體的基本步驟有: 1,用malloc類的函式分配記憶體; 2,用這些記憶體支援應用程式 3,用free函式釋放記憶體 二、動態記憶體分配函式     malloc :從堆上分配記憶體 &nbs

C語言--動態分配記憶體空間的使用方法

#include <stdio.h> #include <stdlib.h> int main() { int i; int *nums; //為指標分配動態的記憶體空間 // nums = (int *)mall

c/c++實現的一個動態分配記憶體的結構體陣列(類似vector)

這個陣列可以向裡面插入任何型別,包括自定義型別, 程式只是實現了基本功能,還有待完善, 首先初始化,然後就可以插入資料了, 當儲存單元不足的時候就自動增加儲存單元 由於總的風格是c, 所以看著很是彆扭, 有空了把全部改成c++風格的; 說有空就有空了,改成了c++風格了,

C語言:動態分配記憶體,malloc()與realloc()區別

#include <stdio.h> #include <stdlib.h> //動態分配記憶體標頭檔案 int main() { /* 何為動態?

C語言為二維陣列動態分配記憶體的問題

C語言中動態分配一位陣列是很簡單的,但是沒有可以直接對二維陣列進行動態分配的函式,因此,要相對二維陣列動態分配記憶體,便要藉助於一位陣列來實現,具體如下: 假設要為一個n*m的二維陣列分配動態

C語言練習題】動態分配記憶體

《C和指標》練習題11.11   問題 編寫一個函式,從標準輸入讀取一列整數,把這些值儲存於一個動態分配的陣列中並返回這個陣列。函式通過觀察EOF判斷輸入列表是否結束。陣列的第一個數是陣列包含的值的個數,他的後面就是這些整數值   程式碼 #inclu

動態分配記憶體 and malloc&new and 陣列的動態分配、初始化(memset)和撤銷(delete)

 在計算機的系統中有四個記憶體區域:1)棧:在棧裡面儲存一些我們定義的區域性變數和形參。2)字元常量區:主要儲存一些字元常量,比如:char *p_str="cat",其中"cat"就儲存於字元常量區裡。3)全域性區:在全域性區裡儲存一些全域性變數和靜態變數4)堆:主要是通過

C/C++動態分配記憶體

本部落格對以下幾篇部落格進行總結歸納:1.   需要動態分配記憶體的原因陣列是最常用的一種資料結構,其缺點是使用時必須確定陣列大小,因此會帶來一些不便:1)需要儲存的資料大小不確定時,預先開闢的空間太小裝不下,太大則浪費空間;2)使用的資料大部分預設儲存在棧(stack)裡,

指標和動態分配記憶體 (不定長度陣列)------新標準c++程式設計

背景:   陣列的長度是定義好的,在整個程式中固定不變。c++不允許定義元素個數不確定的陣列。例如: 1 2 int n; int a[n];  //這種定義是不允許的   但是在實際程式設計中,往往會出現要處理的資料數量在程式設計時無

C++ 何時使用動態分配(即使用newkeyword)?何時使用指針?

指向 delet 問題 con 擁有 才會 屬性 想要 自己 動態分配 在你的問題裏。你用了兩種方式創建對象。這兩種方式基本的不同在於對象的存儲時間。當運行Object myObject;這句代碼時。它作為自己主動變量被創建,這意味著當對象出了作用域時也會自己主動銷毀。

C/C++大數加法動態分配內存

動態分配內存 tgz wot jmx nvl style blank .html zax 84運g2ndtj欣窖http://www.zcool.com.cn/collection/ZMTk1MTM1OTI=.html TS凸晃i23時窒貿0http://www.zcoo