在C中分配字符串是正確的?C內存分配 - char *和char sizeof
char *sample;
sample = malloc (length * sizeof(char));
或
sample = malloc (length * sizeof(char*));
爲什麼char*
佔用4個字節時char
需要1個字節?
在C中分配字符串是正確的?C內存分配 - char *和char sizeof
char *sample;
sample = malloc (length * sizeof(char));
或
sample = malloc (length * sizeof(char*));
爲什麼char*
佔用4個字節時char
需要1個字節?
假設目標是存儲length
字符的字符串,正確的分配是:
sample = malloc(length + 1);
注:
sizeof (char)
,因爲它總是1不添加任何值。length
是字符串的可見字符的長度,即strlen()
的返回值將是length
。malloc()
。原因char *
更大的原因是它是一個指針類型,指針幾乎總是大於單個字符。在很多系統上(比如你的,看起來)它們是32位,而字符只是8位。由於指針需要能夠表示機器內存中的任何地址,所以需要更大的尺寸。在64位計算機上,指針通常是64位,即8個字符。
sample = malloc(length);
是正確的
char*
是一個指針,指針使用4個字節(32位的平臺上說)
char
是char,一個char使用1字節
'length * sizeof(char)+ 1'有點奇怪。我可以理解'(length + 1)* sizeof(char)','length + 1'也可以,但爲什麼在乘法後加1? –
sample = malloc (length * sizeof(char));
首先是正確的一個,如果你想爲length
字符分配內存。
char*
是類型指針,它恰好在您的平臺上是4個字節。因此sizeof(char*)
返回4.
但sizeof(char)
始終爲1,並且smae由C標準保證。
爲什麼當char需要1個字節時char *需要4個字節?
因爲你在32位系統上,這意味着指針需要4個字節; char*
是一個指針。
char
總是帶一個字節,所以你不需要通過sizeof(char)
乘:
sample = malloc (length);
我假設length
已經填補了空終止。
在給定的情況下,你正在做兩件不同的事情:
在第一種情況:sample = malloc (length * sizeof(char));
您分配length
乘以char
類型的大小是1字節
而在第二種情況下:sample = malloc (length * sizeof(char*));
您正在分配length
乘以指針的大小char
即4字節 在您的機器上。
考慮到雖然案例1保持不變,但在第二種情況下,案件的規模是可變的。
在你的情況下,你想分配一個長度字符數組。您將在sample
中存儲一個指向您指向的大小的length
倍數組的指針。 sizeof(char*)
是指向char
的指針的大小。不是char
的大小。
一個好的做法是
sample = malloc(length * sizeof(*sample));
利用這一點,你會預留長度的時間要指向什麼大小。這使您可以隨時更改數據類型,只需將樣本聲明爲另一種數據即可。
int *sample;
sample = malloc(length * sizeof(*sample)); // length * 4
char *sample;
sample = malloc(length * sizeof(*sample)); // length * 1
倘若length
已經佔NUL終止,我會寫兩種:
sample = malloc(length);
或:
sample = malloc(length * sizeof(*sample));
sizeof(char*)
是指針的大小,它是完全與分配的緩衝區所需的大小無關。所以絕對不要使用它。
我的第一個片段是國際海事組織足夠的字符串操作代碼。 C程序員知道C中的內存和字符串長度都是以sizeof(char)
的倍數來衡量的。沒有必要在那裏放置一個轉換系數,每個人都知道它總是1
。
我的第二個片段是一般寫入分配的一種真正方法。所以如果你想讓所有的分配看起來一致,那麼字符串分配也應該使用它。我能想到的兩個可能的原因使所有的分配看起來是一致的(二者相當薄弱IMO,但實際上沒有錯):
sizeof(*sample)
作爲一致形式意味着您根本不需要更改該行代碼,前提是您在測量length
的單位的同時更新sample
的類型。其他選項包括:
sample = calloc(length, 1);
sample = calloc(length, sizeof(char));
sample = calloc(length, sizeof(*sample));
他們可能相當沒有意義在這裏,但還有零內存的瑣碎的輔助效果,calloc
具有malloc
一個有趣的差異,它明確地分開對象的數量和大小您打算使用,而malloc
只是想要的總大小。
對於任何類型T
,通常的形式是
T *p = malloc(N * sizeof *p);
或
T *p;
...
p = malloc(N * sizeof *p);
其中N
是T
要分配類型的元素的數量。表達式*p
具有類型T
,因此sizeof *p
等同於sizeof (T)
。
注意sizeof
是操作者像&
或*
,而不是一個庫功能;如果操作數是類型名稱,例如int
或char *
,則只需要括號。
我記得最後一個空字節謝謝:) – fex
雖然'sizeof(char)'沒有添加任何內容,它使得意圖明確瞭解正在發生的事情。我想這是一個品味問題。 –
@KingsIndian:這是一個你如何閱讀'malloc'調用的問題(我同意這反過來又是一個口味問題)。展開,我會將'malloc(length + 1)'看作爲「分配長度+1字節」或者「分配長度+1字符」,並且知道這兩者在C中意味着完全一樣的東西。有些人可能會讀取它作爲「分配長度+ 1」的東西,但是是什麼?作者沒有說,也許他們不知道!「。對那些讀者來說,在這裏拋出一個明確的'sizeof(char)'可能有助於說服他們我的意思就是我所說的。 –