2012-12-06 96 views
0

在C中分配字符串是正確的?C內存分配 - char *和char sizeof

char *sample; 

sample = malloc (length * sizeof(char)); 

sample = malloc (length * sizeof(char*)); 

爲什麼char*佔用4個字節時char需要1個字節?

回答

6

假設目標是存儲length字符的字符串,正確的分配是:

sample = malloc(length + 1); 

注:

  1. 不要使用sizeof (char),因爲它總是1不添加任何值。
  2. 請記住終止符,我假設(根據名稱)length是字符串的可見字符的長度,即strlen()的返回值將是length
  3. 我知道你沒有,但值得指出的是,也不應該有cast of the return value from malloc()

原因char *更大的原因是它是一個指針類型,指針幾乎總是大於單個字符。在很多系統上(比如你的,看起來)它們是32位,而字符只是8位。由於指針需要能夠表示機器內存中的任何地址,所以需要更大的尺寸。在64位計算機上,指針通常是64位,即8個字符。

+0

我記得最後一個空字節謝謝:) – fex

+2

雖然'sizeof(char)'沒有添加任何內容,它使得意圖明確瞭解正在發生的事情。我想這是一個品味問題。 –

+0

@KingsIndian:這是一個你如何閱讀'malloc'調用的問題(我同意這反過來又是一個口味問題)。展開,我會將'malloc(length + 1)'看作爲「分配長度+1字節」或者「分配長度+1字符」,並且知道這兩者在C中意味着完全一樣的東西。有些人可能會讀取它作爲「分配長度+ 1」的東西,但是是什麼?作者沒有說,也許他們不知道!「。對那些讀者來說,在這裏拋出一個明確的'sizeof(char)'可能有助於說服他們我的意思就是我所說的。 –

1
sample = malloc(length); 

是正確的

char*是一個指針,指針使用4個字節(32位的平臺上說)

char是char,一個char使用1字節

+0

'length * sizeof(char)+ 1'有點奇怪。我可以理解'(length + 1)* sizeof(char)','length + 1'也可以,但爲什麼在乘法後加1? –

1
sample = malloc (length * sizeof(char)); 

首先是正確的一個,如果你想爲length字符分配內存。

char*是類型指針,它恰好在您的平臺上是4個字節。因此sizeof(char*)返回4.

sizeof(char)始終爲1,並且smae由C標準保證。

2

爲什麼當char需要1個字節時char *需要4個字節?

因爲你在32位系統上,這意味着指針需要4個字節; char*是一個指針。

char總是帶一個字節,所以你不需要通過sizeof(char)乘:

sample = malloc (length); 

我假設length已經填補了空終止。

1

在給定的情況下,你正在做兩件不同的事情:

在第一種情況:sample = malloc (length * sizeof(char));

您分配length乘以char類型的大小是1字節

而在第二種情況下:sample = malloc (length * sizeof(char*));

您正在分配length乘以指針的大小char4字節 在您的機器上。

考慮到雖然案例1保持不變,但在第二種情況下,案件的規模是可變的。

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 
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只是想要的總大小。

0

對於任何類型T,通常的形式是

T *p = malloc(N * sizeof *p); 

T *p; 
... 
p = malloc(N * sizeof *p); 

其中NT要分配類型的元素的數量。表達式*p具有類型T,因此sizeof *p等同於sizeof (T)

注意sizeof操作者&*,而不是一個庫功能;如果操作數是類型名稱,例如intchar *,則只需要括號。