size_t——為什么支持size_t,何時使用size_t?


為什么會有 ”size_t為何要存在” 的疑問?

許多C/C++文件中都會出現類型size_t,比如在bitcoin源碼中,有這樣的一個函數:

size_t strnlen( const char *start, size_t max_len)
{
    const char *end = (const char *)memchr(start, '\0', max_len);
    //memchr函數從start開始尋找第一個出現字符'\0'的位置並返回
    return end ? (size_t)(end - start) : max_len;
    //const char的長度吧,為啥要這樣寫,為什么要單獨寫一個文件啊,NOTE
}

該函數完成了返回const char*類型start代表的串的長度,返回值被設置為size_t類型。這是size_t經常被使用的一個場景“數組可能的長度

另一個使用場景就是函數memcpy(其實本質上是一樣的,都是表示內存中數據的多少)。memcpy的原型void* memcpy(void*to,const void*from,size_t n)。需要復制的字節數被設置為size_t類型,這是數據塊的大小

於是,會給人一種感覺,這種工作int也可以完成,如果說需要排除負數,unsigned int也可以完成。為什么要多此一舉引入size_t呢?

另外,為何要表示內存中所有的數據呢?為什么不是硬盤?
這就是操作系統范疇的東西了。程序所使用的數據,一定是先由OS把數據搬/swap到內存,再根據內存地址去訪問。至於怎么從硬盤中找到,就是另一件事情了,它被叫做”缺頁中斷“。

為什么需要size_t?

首先聲明size_t的功能,它需要保證在程序運行中可以表示所有內存地址。size_t根據具體機器的體系結構,將有不同的值。比如,32位系統,內存最大是\(2^{32} bytes=4G\)。那么size_t就需要至少4個字節(32bits)來表示所有地址。

即使是這樣,unsigned int不是也是4個字節嗎?
有些系統是。

為了保證在一些有者特殊體系結構的機器上正確運行,使用unsigned int來表示數據塊大小可能是一個不好的主意。比如,一個機器支持16bit的unsigned int,但他是一個32位系統,使用unsigned int代替size_t顯然並不是一個好主意。假如出現一個特別大的數組,可能無法表示出這個數組所有的元素,顯而易見。
那么,是否可以使用unsigned long來代替呢?畢竟,long一定需要至少32bits,那么,對於那些只有16位的平台呢,這些平台往往使用兩個16bits的字來對應一個long,在對long進行操作時,一定需要至少兩條操作指令。而在這個系統中,並不需要32bits的地址,因為他只有16位。
要為了兼容而舍棄性能嗎?顯然有更好的解決方案。那就是根據地址總線個數來決定一個類型的大小,既不會無法表示一些數據,又不會使一些機器效率折損。這個類型就是size_t
size_t的存在使得程序有更好的可移植性,顯而易見,程序員不需要為了一個新機器而在unsigned intunsigned char等等類型之間改來改去。

size_t的使用

正如上述,size_t可以表示內存中的所有數據,因為它剛好能夠表示內存中所有的地址。
根據定義,size_t是關鍵字sizeof運算得到的結果的類型。因此,使用sizeof得到的結果應該聲明為size_t

size_t n=sizeof(int)

另外,就是第一小節所述的,表示數組大小、數據塊大小等等(實際上也是數據塊的大小)。

使用size_t的時候,記得包括它的定義所在頭文件,比如<stddef.h>, <stdio.h>, <stdlib.h>, <string.h>, <time.h>,<wchar.h>中的任意一個。

Reference

為什么size_t重要?
size_t類型


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM