Re: [問題] 請問一下為何要使用new?
我們把原本的 code 整理一下吧,
int a = 10;
int *pa;
pa = new int;
pa = &a;
*pa = 20;
說明時主要以此例為架構,
接下來畫圖時間,下面述敘我比較少看到課本說明,
只考慮基本資料型態 POD 型態 (int, char, short, long long, double..etc)
不考慮 struct, class, 等自定義型態;
亦不考慮程式碼中有被 compiler 優化過。
※ 引述《sd016808 ()》之銘言:
1. 直接給值
int a;
當作這動作時,程式會自己在憶體裡面找一個位址放 a 。
由於 int 這大小是 4 bytes, 所以會直接分配一個 4bytes 大小位址給 a
Var. int a
┌──┬─────┬──┬──┬──┬──┬──┬──┬──┬──┐
Addr │... │ 0x12~0x15│ │ │ │ │ │ │ │ │
┌──┬─────┬──┬──┬──┬──┬──┬──┬──┬──┐
Value │... │ ??????? │ │ │ │ │ │ │ │ │
└──┴─────┴──┴──┴──┴──┴──┴──┴──┴──┴
一樣的,今天做了「宣告同時給初值時」,動作類似,唯一開始就在 Addr 給初值。
int b=10;
Var. int a int b
┌──┬─────┬──┬─────┬──┬──┬──┬──┬──┐
Addr │... │ 0x12~0x15│... │0x20~0x23 │ │ │ │ │ │
┌──┬─────┬──┬─────┬──┬──┬──┬──┬──┐
Value │... │ ??????? │... │ 10 │ │ │ │ │ │
└──┴─────┴──┴─────┴──┴──┴──┴──┴──┴
a = b;
而這段敘述是,程式到 b 的位址撈值出來,丟給 a,所以最後 a 裡面的值就是 b
Var. int a int b
┌──┬─────┬──┬─────┬──┬──┬──┬──┬──┐
Addr │... │ 0x12~0x15│... │0x20~0x23 │ │ │ │ │ │
┌──┬─────┬──┬─────┬──┬──┬──┬──┬──┐
Value │... │ 10 │... │ 10 │ │ │ │ │ │
└──┴─────┴──┴─────┴──┴──┴──┴──┴──┴
上面這些,變數對應到哪個位址,都是由程式掌控。
2. 間接給值 (pointer)
假設一開始只有 int a;
Var. int a
┌──┬─────┬──┬──┬──┬──┬──┬──┬──┬──┐
Addr │... │ 0x12~0x15│ │ │ │ │ │ │ │ │
┌──┬─────┬──┬──┬──┬──┬──┬──┬──┬──┐
Value │... │ ??????? │ │ │ │ │ │ │ │ │
└──┴─────┴──┴──┴──┴──┴──┴──┴──┴──┴
再來是先宣告一個指向整數的指標,
注意到,只要是指標,它存的 永遠都是記憶體的位置值 (開頭位置),
既然是存位置,所以記憶體給它的大小永遠都是固定的。故
int *pa;
double *pa;
char *pa;
不論是哪種,都是給它 4bytes (假給程式都是固定給指標 4bytes 存位置)
現在要藉由指標,讀寫 a ,而 a 的資料型態是 int,故宣告成指向int之指標
int *pa;
只有這樣宣告時,記憶體配了一個空間 (剛說了,假設是 4bytes) 給 pa
Var. int a int *pa
┌──┬─────┬──┬──┬─────┬──┬──┬──┬──┐
Addr │... │ 0x12~0x15│... │ │0x20~0x23 │ │ │ │ │
┌──┬─────┬──┬──┬─────┬──┬──┬──┬──┐
Value │... │ ??????? │... │ │ ??????? │ │ │ │ │
└──┴─────┴──┴──┴─────┴──┴──┴──┴──┴
而第三步驟時, pa = new int;
這動作事實上是由二個動作合併成一個的。
一開始程式找一個新的空間配一個 int 大小記憶體 (4bytes) 出來,
而這個空間標示成 _address,假設這新的空間是
Var. int a int *pa _address
┌──┬─────┬──┬──┬─────┬──┬─────┬──┐
Addr │... │ 0x12~0x15│... │ │0x20~0x23 │ │ 0x30~0x33│ │
┌──┬─────┬──┬──┬─────┬──┬─────┬──┐
Value │... │ ??????? │... │ │ ??????? │ │ ????? │ │
└──┴─────┴──┴──┴─────┴──┴─────┴──┴
再來才把 _address 這個「位置」丟給 pa,所以 pa 現在存的就是那份新位置開頭,
也就是 0x30
Var. int a int *pa _address
┌──┬─────┬──┬──┬─────┬──┬─────┬──┐
Addr │... │ 0x12~0x15│... │ │0x20~0x23 │ │ 0x30~0x33│ │
┌──┬─────┬──┬──┬─────┬──┬─────┬──┐
Value │... │ ??????? │... │ │ 0x30 │ │ ????? │ │
└──┴─────┴──┴──┴─────┴──┴─────┴──┴
pa = &a;
接下來這動作,又把 a 取位置 (&a),再丟到 pa 的內容去。
( 因為 pa 是指標,所以一定是存「位置值」 )
Var. int a int *pa _address
┌──┬─────┬──┬──┬─────┬──┬─────┬──┐
Addr │... │ 0x12~0x15│... │ │0x20~0x23 │ │ 0x30~0x33│ │
┌──┬─────┬──┬──┬─────┬──┬─────┬──┐
Value │... │ ??????? │... │ │ 0x12 │ │ ????? │ │
└──┴─────┴──┴──┴─────┴──┴─────┴──┴
*pa = 20;
這行動作,也同等拆也二部份,一開始 *pa ,
根據 pa 裡面存的 0x12,去標記 0x12 為 _addr2
_addr2
Var. int a int *pa _address
┌──┬─────┬──┬──┬─────┬──┬─────┬──┐
Addr │... │ 0x12~0x15│... │ │0x20~0x23 │ │ 0x30~0x33│ │
┌──┬─────┬──┬──┬─────┬──┬─────┬──┐
Value │... │ ??????? │... │ │ 0x12 │ │ ????? │ │
└──┴─────┴──┴──┴─────┴──┴─────┴──┴
再來再整段看, *pa=20,去把剛剛標記的 _addr2 改成 20
_addr2
Var. int a int *pa _address
┌──┬─────┬──┬──┬─────┬──┬─────┬──┐
Addr │... │ 0x12~0x15│... │ │0x20~0x23 │ │ 0x30~0x33│ │
┌──┬─────┬──┬──┬─────┬──┬─────┬──┐
Value │... │ 20 │... │ │ 0x12 │ │ ????? │ │
└──┴─────┴──┴──┴─────┴──┴─────┴──┴
檢視剛剛的成果出來
int a;
int *pa;
pa = &a;
*pa = 20
所以最後用了 pa 去改 a 值,
cout << a << endl; 和
cout << *pa << endl;
答案都是 20,原理上面都已說明。
至於剛剛先用到的 pa = new int; ,那份 _address 到現在還卡在記憶體裡面,
以後就沒辦法再去控管它了,稱 memory leak。
至於 memory leak 現象這有很多說明了,本文不探討。
若是卡在 new 是什麼意思不知道 ---> 只能說該死了。
: 開發平台(Platform): (Ex: VC++, GCC, Linux, ...)
: BCB
: 問題(Question):
: 想請問一下new所代表的意思?
: 例如
: int a=3,*ptr;
: char buff[3];
: ptr=new int;// 這行代表說建立一個int大小的空間並讓ptr指定?
: ptr=&a;
: sprintf(buff,"%d",*ptr);
: Edit1->Text=buff;
: 想請問一下有打第3行跟沒有打 到底有什麼差別?
--
No matter how gifted you are,
alone, can not change the world.
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.78.41
→
11/23 17:45, , 1F
11/23 17:45, 1F
→
11/23 17:45, , 2F
11/23 17:45, 2F
→
11/23 17:47, , 3F
11/23 17:47, 3F
推
11/23 17:53, , 4F
11/23 17:53, 4F
推
11/23 18:32, , 5F
11/23 18:32, 5F
→
11/23 19:39, , 6F
11/23 19:39, 6F
推
11/23 20:41, , 7F
11/23 20:41, 7F
→
11/23 22:07, , 8F
11/23 22:07, 8F
→
11/23 22:08, , 9F
11/23 22:08, 9F
推
11/23 23:16, , 10F
11/23 23:16, 10F
→
11/23 23:16, , 11F
11/23 23:16, 11F
→
11/23 23:20, , 12F
11/23 23:20, 12F
→
11/23 23:22, , 13F
11/23 23:22, 13F
→
11/23 23:23, , 14F
11/23 23:23, 14F
→
11/23 23:27, , 15F
11/23 23:27, 15F
→
11/24 00:55, , 16F
11/24 00:55, 16F
→
11/24 00:56, , 17F
11/24 00:56, 17F
→
11/24 00:56, , 18F
11/24 00:56, 18F
→
11/24 09:09, , 19F
11/24 09:09, 19F
→
11/24 09:10, , 20F
11/24 09:10, 20F
→
11/24 18:42, , 21F
11/24 18:42, 21F
推
11/24 22:12, , 22F
11/24 22:12, 22F
推
02/01 21:55, , 23F
02/01 21:55, 23F
討論串 (同標題文章)