2013-12-19 48 views
10

當動態分配char S,我一直在做這樣的:動態分配'char'冗餘時是否使用'sizeof(char)'?

char *pCh = malloc(NUM_CHARS * sizeof(char)); 

我最近被告知,但是,使用sizeof(char)是定義多餘的,不必要的,因爲,」的大小char是一個字節,」所以我應該/能寫上一行:

char *pCh = malloc(NUM_CHARS); 

我的理解是一個字符的大小取決於被在目標計算機上使用的本地字符集。例如,如果本地字符集是ASCII,則char是一個字節(8位),並且如果本地字符集是UNICODE,那麼char將需要更多字節(> 8位)。

爲了提供最大的便攜性,是否有必要使用sizeof(char),因爲malloc只是簡單地分配8位字節?我誤解了mallocsizeof(char)

+0

+1忽略了不需要的'(char *)'在右邊投上 – Bathsheba

+3

我會'char * pCh = malloc(NUM_CHARS * sizeof(* pCh));'並轉向其他問題。 – alk

+0

s/right/left /,right @Bathsheba? – unwind

回答

14

是的,這是多餘的,因爲該語言標準規定sizeof (char)是1。這是因爲,是在其中的東西被測量的單元,所以當然的單元的大小本身必須是1

生命變得很陌生,根據自己的定義單位,這根本沒有任何意義。許多人似乎「想」假設「有8位字節,並且sizeof告訴我有多少這樣的特定值」。這是錯的,那根本不是它的工作原理。的確,可以有比8位更大的字符的平臺,這就是爲什麼我們有CHAR_BIT

通常你總是「知道」,當你無論如何分配字符,但如果你真的想包括sizeof,你真的應該考慮將它使用指針,而不是:

char *pCh = malloc(NUM_CHARS * sizeof *pCh); 

這種「鎖」事物的單位大小被分配了用於存儲分配結果的指針。這兩種類型應該匹配,如果你看到這樣的代碼:

int *numbers = malloc(42 * sizeof (float)); 

這是一個巨大的警告信號;通過使用從左邊的指針在sizeof您作出這樣的類型,我認爲一個巨大的勝利錯誤是不可能的:

int *numbers = malloc(42 * sizeof *numbers); 

而且,很可能是,如果你改變指針的名稱,malloc()如果你有那裏的(錯誤的)基本類型的名字,它將不會編譯它。如果你忘記了星號(並且寫入sizeof numbers而不是sizeof *numbers),則存在輕微的風險,您將無法獲得所需的內容。在實踐中(對我來說)這似乎從來沒有發生過,因爲作爲這種模式的一部分,星號已經很好地建立在我身上了。此外,此用法依賴於(並強調)sizeof不是函數,因爲在指針解除引用表達式周圍不需要()。這是一個很好的獎勵,因爲很多人似乎都想否認這一點。 :)

我覺得這種模式非常令人滿意,並推薦給大家。

+0

你應該早點回答,我會給你正確的答案。 –

+0

@BitFiddlingCodeMonkey Aawww。謝謝。 :)如果你願意,我相信你可以移動被接受的地位。 [見這個元問題](http://meta.stackexchange.com/questions/62252/is-it-poor-form-to-switch-accepted-answers)。 – unwind

4

C規範指出sizeof(char)1,所以只要您處理C的符合實現,它就是多餘的。

malloc使用的尺寸單位是相同的。 malloc(120)分配空間給120 char

A char必須至少爲8位,但可能會更大。

+0

因此,在具有16位'char',以8位的倍數分配內存是不可能的? –

+0

@BitFiddlingCodeMonkey:正好。關鍵是'char'(= byte)被定義爲最小的可尋址數據類型(只要大於8位),所以具有更好的粒度是沒有意義的。 –

+0

@BitFiddlingCodeMonkey:你不能在這樣的系統上請求24位。 'malloc(1)'通常會由於內存對齊而分配4個字節,所以我沒有看到問題。 –

2

sizeof(char)總是1,但這並不是因爲char總是一個字節(它不必是),而是因爲sizeof操作者返回的char單位的對象/類型的大小。

+0

'char'通常*是*「平臺字節」(=最小的可尋址數據類型),問題是不是所有平臺上的字節都是八位字節。 –

5

C99 draft standard6.5.3.4sizeof運算段落狀態:

當應用於具有類型char,無符號的字符,或符號的字符, 一個操作數(或其合格版本)結果爲1 [...]

在C11標準草案它是第4 措辭是一樣。所以NUM_CHARS * sizeof(char)應該相當於NUM_CHARS

我們可以從字節的定義3.6看到,這是一個:

數據存儲大到足以容納的基本特徵 集執行環境的任何成員的

尋址單元

注2說:

一個字節由一個連續的位序列組成,其數量是實現定義的。最低有效位稱爲低位;最重要的位稱爲高位。

3

sizeof(char)將始終返回1,因此,如果使用它或無關緊要,它不會改變。你可能會混淆這與UNICODE寬字符,它有兩個字節,但他們有不同的類型wchar_t所以你應該使用sizeof在這種情況下。

如果您正在制定一個字節定義爲16位的系統,那麼sizeof(char)仍然會返回1,因爲這是底層架構將分配的內容。 1個字節,16位。

+0

因此,如果系統中有1個字節是16位,那麼'malloc'總是返回16位的倍數,也就是說,你不能動態地分配多個8位? –

+1

是的,如果這是機器的規格,那就是這樣。編譯器只是反映了這種設計。在這樣的機器上,你不能少於16位。所以如果你使用'malloc(2)',你會得到一個指向兩個字節的指針,但是由32位組成。 – Devolus

3

分配大小總是以char爲單位進行測量,其大小爲1 由定義。如果您使用的是9位機器,則malloc會將其參數理解爲多個9位字節。

+0

你是否在使用'9位'作爲假設的例子?我從來沒有聽說過這樣的事情。 –

+2

@BitFiddlingCodeMonkey:IIRC一些大型機使用9位字節 - 可能是由於36位字。現在,在DSP中通常會發現奇怪的比特大小,每個字節往往有12到16比特。請參閱[這裏](http://stackoverflow.com/questions/5516044/system-where-1-byte-8-bit)瞭解一些真實世界的例子。 –

相關問題