[問題] malloc's buffer size

看板C_and_CPP作者 (EngRookie)時間9年前 (2016/08/04 15:50), 9年前編輯推噓16(16039)
留言55則, 20人參與, 最新討論串1/1
小弟今天突然發現原來自己對 malloc 超級不熟.... 舉個例子 char *str = (char *)malloc(sizeof(char)); 就我理解他是回傳一個char型態的位址,並且長度為1個 byte 但是我居然可以在裡面塞下很多東西,如下: strcpy(str, "a"); printf("%s\n", str); strcat(str, "b"); printf("%s\n", str); strcat(str, "c"); printf("%s\n", str); 一樣可以印出 a, ab, abc 問題:str的buffer size到底是多少呢? 要怎麼印出來......(已爬文過 T___T -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 61.220.255.38 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1470297028.A.480.html

08/04 16:34, , 1F
不太懂問題,是問只有malloc一個char的str怎麼能strcpy那
08/04 16:34, 1F

08/04 16:34, , 2F
麼多次沒爆炸嗎?
08/04 16:34, 2F

08/04 16:36, , 3F
印大小的話,呼叫sizeof再印出來呀?
08/04 16:36, 3F

08/04 16:47, , 4F
1. 可以編譯也可以執行 2. sizeof 沒辦法印出malloc
08/04 16:47, 4F

08/04 16:48, , 5F
1
08/04 16:48, 5F

08/04 16:50, , 6F
但你應該malloc(sizeof(char)+1)
08/04 16:50, 6F
這個我知道,但是我想知道為什麼我可以再一個byte的空間裡面塞入多個字串 ※ 編輯: EngRookie (61.220.255.38), 08/04/2016 16:54:57

08/04 16:57, , 7F
因為你一直copy到同個位置
08/04 16:57, 7F

08/04 16:59, , 8F
為什麼我只有一個杯子 每天卻可以喝那麼多水
08/04 16:59, 8F
不好意思,我有點不了解,我再同一個記憶體位置放入"a",那麼我 strcat(str, "b")時,這個b應該是會放入 str+1 的位置 但是很明顯我並沒有分配 str+1 的位置出來,是我觀念有點問題嗎 T___T ※ 編輯: EngRookie (61.220.255.38), 08/04/2016 17:14:11

08/04 17:16, , 9F
你租一間套房但自己把牆壁打掉佔用隔壁間 有沒有問題?
08/04 17:16, 9F

08/04 17:16, , 10F
在房客回來或房東報警前當然是沒有啦...
08/04 17:16, 10F

08/04 17:24, , 11F
如果你的str是"a\0",那strcat就會放在str+1
08/04 17:24, 11F

08/04 17:24, , 12F
如果你的str是a,沒有null-terminated character,那就
08/04 17:24, 12F

08/04 17:25, , 13F
是undefined behavior
08/04 17:25, 13F

08/04 17:34, , 14F
原 po 只是單純想問存取越界為什麼不會爆炸吧
08/04 17:34, 14F
我大概了解原來記憶體位置可以這樣越界操作,我之前都乖乖把記憶體範圍算好好的 謝謝各位大大的解釋 ※ 編輯: EngRookie (61.220.255.38), 08/04/2016 17:36:31

08/04 17:35, , 15F
這問題很深 要從 data segement, heap, brk() system
08/04 17:35, 15F

08/04 17:35, , 16F
call 開始說起
08/04 17:35, 16F

08/04 17:36, , 17F
你可以想像 brk() 會跟 OS 要多一點的 heap 空間
08/04 17:36, 17F

08/04 17:36, , 18F
但是呼叫這樣一個 system call 是需要時間的
08/04 17:36, 18F

08/04 17:36, , 19F
所以 malloc() 傾向拿多一點的空間 而不會拿剛剛好
08/04 17:36, 19F

08/04 17:36, , 20F
但是使用者呼叫 malloc(sizeof char) 就只有要求 1 btye
08/04 17:36, 20F

08/04 17:37, , 21F
所以 malloc 本身的紀錄會僅有 1 byte 被用掉
08/04 17:37, 21F

08/04 17:37, , 22F
但事實上因為空間有多要一點 所以後面是很可能可以存取的
08/04 17:37, 22F

08/04 17:37, , 23F
但這是 undefined behavior, 沒有人可以保證會發生甚麼事
08/04 17:37, 23F

08/04 17:38, , 24F
如果你剛好用完 brk() 要到的空間 接下來就噴 segement
08/04 17:38, 24F

08/04 17:38, , 25F
fault 了
08/04 17:38, 25F

08/04 17:40, , 26F
樓上強者大大Orz
08/04 17:40, 26F

08/04 17:40, , 27F
樓上廚
08/04 17:40, 27F

08/04 17:53, , 28F
你只租了一間房間,但是你的東西擺到隔壁去了
08/04 17:53, 28F

08/04 19:05, , 29F
範圍算得好好的是好習慣,記得這次只是剛好讓你沒事
08/04 19:05, 29F

08/04 22:10, , 30F
Windows 上有 _msize() https://goo.gl/e4uFgA 請慎用
08/04 22:10, 30F

08/04 22:13, , 31F
Linux 上 malloc 會根據配置大小來決定用 brk 或 mmap
08/04 22:13, 31F

08/04 22:13, , 32F
glibc 有 malloc_usable_size 但也請慎用就是
08/04 22:13, 32F

08/05 10:20, , 33F
看緩衝區溢位的時候有提過申請空間得到的會比原本來的多
08/05 10:20, 33F

08/05 10:20, , 34F
,可是大小不知道多少,是這個意思吧
08/05 10:20, 34F

08/05 10:26, , 35F
不可能每次都要剛剛好 一定會多要為了效率
08/05 10:26, 35F

08/05 10:26, , 36F
memory poool就是自己掌控多要多少 啥時還回去來提升
08/05 10:26, 36F

08/05 10:27, , 37F
效率
08/05 10:27, 37F

08/05 10:27, , 38F
常用的像一次要一個page 和free list
08/05 10:27, 38F

08/05 11:22, , 39F
heap要segmentation fault可能要overflow之後
08/05 11:22, 39F

08/05 11:23, , 40F
又呼叫malloc/free比較容易發生
08/05 11:23, 40F

08/05 17:02, , 41F
原來是strcat 我看成strcpy (遮臉
08/05 17:02, 41F

08/05 17:40, , 42F
你可以另外宣告一個指標在str後面一點點,然後一樣給值
08/05 17:40, 42F

08/05 17:41, , 43F
再去亂玩str,馬上就會理解問題了
08/05 17:41, 43F

08/05 17:58, , 44F
你只買了一張火車票 但是把行李放在隔壁的座位上
08/05 17:58, 44F

08/05 17:59, , 45F
會不會被趕? 不知道 運氣好就放到下車 運氣不好就被趕
08/05 17:59, 45F

08/05 23:14, , 46F
應該是運氣不好別人直接一屁股坐在你行李上XD
08/05 23:14, 46F

08/06 01:01, , 47F
我怎麼覺得坐下去整台火車就炸了 XD
08/06 01:01, 47F

08/07 13:07, , 48F
原po可看看虛擬記憶體映射,上面的code說不定把別的mallo
08/07 13:07, 48F

08/07 13:08, , 49F
c 數值改了
08/07 13:08, 49F

08/12 20:15, , 50F
越界本來就不一定爆炸
08/12 20:15, 50F

10/21 04:30, , 51F
一堆人比喻的內容根本看不懂..
10/21 04:30, 51F

10/21 04:33, , 52F
不就os call malloc 都會偷拿額外的memory 嗎? 因
10/21 04:33, 52F

10/21 04:33, , 53F
為每次用system call都是很大的cost 系統為了省時間
10/21 04:33, 53F

10/21 04:33, , 54F
才會有這種機制
10/21 04:33, 54F

10/21 04:34, , 55F
這樣你下一次用malloc很快就會拿到了
10/21 04:34, 55F
文章代碼(AID): #1NelF4I0 (C_and_CPP)