面试官问:malloc(0)时程序会返回什么?
今天跟大家找了篇文章,主要是一個(gè)面試中的有趣問題,其實(shí)有些問題在開發(fā)中沒有遇到過會(huì)很難回答出來,如果在面試過程中回答正確,皆大歡喜,拿到offer的概率更大;回答不出來也不要信口開河,面試官主要看的是你對(duì)待問題的態(tài)度~
正文:
故事要從前兩天交流群中一位同學(xué)提到的這個(gè)問題開始
這個(gè)問題看起來十分刁鉆,不過稍有常識(shí)的人都知道,制定 C 標(biāo)準(zhǔn)的那幫語言律師也不是吃白飯的,對(duì)這種奇奇怪怪的問題一定會(huì)有定義。翻閱C17 標(biāo)準(zhǔn) 草案 N2176,在 7.22.3 節(jié)里,有如下說法:
The order and contiguity of storage allocated by successive calls to the aligned_alloc, calloc, malloc, and realloc functions is unspecified. The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object with a fundamental alignment requirement and then used to access such an object or an array of such objects in the space allocated (until the space is explicitly deallocated). The lifetime of an allocated object extends from the allocation until the deallocation. Each such allocation shall yield a pointer to an object disjoint from any other object. The pointer returned points to the start (lowest byte address) of the allocated space. If the space cannot be allocated, a null pointer is returned. If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned to indicate an error, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.
在這里,標(biāo)準(zhǔn)委員會(huì)明確規(guī)定了:當(dāng) malloc 接到的參數(shù)為 0 時(shí),其行為是由實(shí)現(xiàn)定義的(implementation-defined)。
由實(shí)現(xiàn)定義的行為這個(gè)詞就提醒我們,在實(shí)際編程時(shí)如果要考慮到程序在多個(gè)運(yùn)行環(huán)境下進(jìn)行運(yùn)行時(shí),不能對(duì) malloc 返回的數(shù)值進(jìn)行任何假設(shè)。
換言之,沒事兒不要吃飽了撐的在實(shí)際編程中寫下 malloc(0) 這種天怒人怨的代碼。
但是,這個(gè)無意義的問題吸引了我的興趣。因此我開始查閱 glibc 的源代碼,依此了解在 glibc 下,mallloc(0) 的行為。在 glibc2.27/malloc/malloc.c 中,有如下注釋:
/*malloc(size_t?n)Returns?a?pointer?to?a?newly?allocated?chunk?of?at?least?n?bytes,?or?nullif?no?space?is?available.?Additionally,?on?failure,?errno?isset?to?ENOMEM?on?ANSI?C?systems.If?n?is?zero,?malloc?returns?a?minumum-sized?chunk.?(The?minimumsize?is?16?bytes?on?most?32bit?systems,?and?24?or?32?bytes?on?64bitsystems.)??On?most?systems,?size_t?is?an?unsigned?type,?so?callswith?negative?arguments?are?interpreted?as?requests?for?huge?amountsof?space,?which?will?often?fail.?The?maximum?supported?value?of?ndiffers?across?systems,?but?is?in?all?cases?less?than?the?maximumrepresentable?value?of?a?size_t. */注釋已經(jīng)說的很清楚了,當(dāng)我們執(zhí)行 malloc(0) 時(shí),我們實(shí)際會(huì)拿到一個(gè)指向一小塊內(nèi)存的指針,這個(gè)指針指向的(分配給我們的)內(nèi)存的大小是由機(jī)器決定的。
細(xì)讀代碼,可以發(fā)現(xiàn),將讀入的內(nèi)存大小進(jìn)行轉(zhuǎn)換是由宏 checked_request2size 實(shí)現(xiàn)的。
相關(guān)的宏定義如下:
/*?pad?request?bytes?into?a?usable?size?--?internal?version?*/ #define?request2size(req)?????????????????????????????????????????\(((req)?+?SIZE_SZ?+?MALLOC_ALIGN_MASK?<?MINSIZE)????????????????\MINSIZE?:??????????????????????????????????????????????????????\((req)?+?SIZE_SZ?+?MALLOC_ALIGN_MASK)?&?~MALLOC_ALIGN_MASK)/*?Same,?except?also?perform?an?argument?and?result?check.??First,?we?checkthat?the?padding?done?by?request2size?didn't?result?in?an?integeroverflow.??Then?we?check?(using?REQUEST_OUT_OF_RANGE)?that?the?resultingsize?isn't?so?large?that?a?later?alignment?would?lead?to?another?integeroverflow.??*/#define?checked_request2size(req,?sz)?\ ({????????\(sz)?=?request2size?(req);?????\if?(((sz)?<?(req))??????\||?REQUEST_OUT_OF_RANGE?(sz))?\{????????\__set_errno?(ENOMEM);?????\return?0;???????\}????????\ })也就是說,我們能申請(qǐng)到的數(shù)值最小為 MINSIZE ,這個(gè) MINSIZE 的相關(guān)定義如下:
/*?The?smallest?possible?chunk?*/ #define?MIN_CHUNK_SIZE????????(offsetof(struct?malloc_chunk,?fd_nextsize)) /*?The?smallest?size?we?can?malloc?is?an?aligned?minimal?chunk?*/ #define?MINSIZE??\(unsigned?long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK)?&?~MALLOC_ALIGN_MASK))/*?The?corresponding?bit?mask?value.??*/ #define?MALLOC_ALIGN_MASK?(MALLOC_ALIGNMENT?-?1) /*?MALLOC_ALIGNMENT?is?the?minimum?alignment?for?malloc'ed?chunks.??Itmust?be?a?power?of?two?at?least?2?*?SIZE_SZ,?even?on?machines?forwhich?smaller?alignments?would?suffice.?It?may?be?defined?as?largerthan?this?though.?Note?however?that?code?and?data?structures?areoptimized?for?the?case?of?8-byte?alignment.??*/ #define?MALLOC_ALIGNMENT?(2?*?SIZE_SZ?<?__alignof__?(long?double)?\??__alignof__?(long?double)?:?2?*?SIZE_SZ)#ifndef?INTERNAL_SIZE_T #?define?INTERNAL_SIZE_T?size_t #endif/*?The?corresponding?word?size.??*/ #define?SIZE_SZ?(sizeof?(INTERNAL_SIZE_T))/*This?struct?declaration?is?misleading?(but?accurate?and?necessary).It?declares?a?"view"?into?memory?allowing?access?to?necessaryfields?at?known?offsets?from?a?given?base.?See?explanation?below. */struct?malloc_chunk?{INTERNAL_SIZE_T??????mchunk_prev_size;??/*?Size?of?previous?chunk?(if?free).??*/INTERNAL_SIZE_T??????mchunk_size;???????/*?Size?in?bytes,?including?overhead.?*/struct?malloc_chunk*?fd;?????????/*?double?links?--?used?only?if?free.?*/struct?malloc_chunk*?bk;/*?Only?used?for?large?blocks:?pointer?to?next?larger?size.??*/struct?malloc_chunk*?fd_nextsize;?/*?double?links?--?used?only?if?free.?*/struct?malloc_chunk*?bk_nextsize; };//?GCC?提供 /*?Offset?of?member?MEMBER?in?a?struct?of?type?TYPE.?*/ #define?offsetof(TYPE,?MEMBER)?__builtin_offsetof?(TYPE,?MEMBER)至此,我們就可以根據(jù)這些計(jì)算出使用 glibc 在我們的電腦上運(yùn)行時(shí) malloc 出的最小空間的大小了。計(jì)算完后,還可以根據(jù) malloc_usable_size 判斷自己的計(jì)算是否正確,樣例代碼如下:
#include?<stdio.h> #include?<malloc.h> int?main(void)?{char?*p?=?malloc(0);printf("Address:?0x%x.\nLength:?%ld.\n",p,malloc_usable_size(p));return?0; }該樣例在我電腦內(nèi)輸出的結(jié)果為 24。
因此,我們知道了,在 glibc 下,執(zhí)行 malloc 會(huì)得到一個(gè)指向分配給我們的大小為 24 字節(jié)的內(nèi)存空間的指針。
但這只是在 glibc 下的結(jié)果,在其他 C 標(biāo)準(zhǔn)庫實(shí)現(xiàn)內(nèi),可能你會(huì)得到一個(gè)空指針。因?yàn)闃?biāo)準(zhǔn)中提到了,對(duì)于 malloc(0) 這種故意挑事的代碼,實(shí)現(xiàn)時(shí)可以返回一個(gè)空指針作為回禮。
素材源于:文章來源:https://zhuanlan.zhihu.com/p/40490357
直接來源:嵌入式與linux那些事
版權(quán)歸原作者所有。僅供技術(shù)的傳播和學(xué)習(xí)討論,如涉及作品版權(quán)問題,請(qǐng)聯(lián)系我進(jìn)行刪除。
推薦閱讀:
專輯|Linux文章匯總
專輯|程序人生
專輯|C語言
我的知識(shí)小密圈
關(guān)注公眾號(hào),后臺(tái)回復(fù)「1024」獲取學(xué)習(xí)資料網(wǎng)盤鏈接。
歡迎點(diǎn)贊,關(guān)注,轉(zhuǎn)發(fā),在看,您的每一次鼓勵(lì),我都將銘記于心~
總結(jié)
以上是生活随笔為你收集整理的面试官问:malloc(0)时程序会返回什么?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 这三个Offer,你怎么选?
- 下一篇: 海康威视网络摄像头开发流程(七)----