2017-06-19 47 views
1

請考慮以下聲明:爲什麼str [5],str [] =「1234」和str = malloc(5)具有不同的大小?

char str1[5]; 
char str2[] = "1234"; 
char *str3 = malloc(sizeof(char) * 5); 

每個str的大小印刷:

printf("str1 has size %ld\n", sizeof(str1)); 
printf("str2 has size %ld\n", sizeof(str2)); 
printf("str3 has size %ld\n", sizeof(str3)); 

輸出是:

str1 has size 5 
str2 has size 5 
str3 has size 8 

我已經理解的是,指針的大小是8個字節。在這3種情況下,str是一個指針,而*str對應於字符串str的第一個字符:在這3種情況下,其大小爲1個字節,其大小爲char

如果我讓程序使用char str[] = "1234"char str[5];str分配5個字節的內存,則str的大小爲5個字節。但是當我分配5個字節到char *strmalloc時,str的大小仍然是8個字節,這是一個指針的大小。我預計str3的大小對應於我用malloc分配給它的內存量。

爲什麼我錯了?

+0

因爲前兩個是五個'char's陣列的,而最後一個是一個指針。無論你分配給'str3','sizeof'的結果都不會改變。 – dasblinkenlight

+0

'sizeof'不會告訴你數據的大小;只是* type *的大小。 'sizeof char [5]'是'5'。 'sizeof char [100]'是100.'sizeof char *'總是8(在你的機器上); – RPGillespie

回答

2

TL; DR - Arrays are not pointers and vice-versa

在代碼中,str1str2「陣列」,並str3「指針」。它們的尺寸根據各自的類型進行打印。

  • str1根據定義有5個char元素。
  • str2也有5 char元素,初始值+空終止符。
  • str3是一個指針,所以sizeof(str3) === sizeof(char *) [注:這取決於環境,它不是固定的,最常用的值是8(64位RACH)和4(32位拱)]

FWIW,使用%zu打印輸出sizeof運營商,因爲它是size_t類型。

+0

哦,好吧,我以爲數組是指針? – nounoursnoir

+0

@nounoursnoir __不,他們不是___。參見C-FAQ,第6章。 –

+0

@nounoursnoir一個數組可以*衰減*到指向其第一個元素的指針(當將數組傳遞給函數時會發生這種情況),但它本身不是指針。 –

1

取指針的大小爲指針的大小,而不是它指向的內容。你得到的大小是8意味着你在64位系統中指針是64位(8字節)。

數組是固定大小的內存塊,並且使用sizeof運算符會給出該塊的大小。

+0

好吧...使用'sizeof(* str)'輸出我'1' – nounoursnoir

+1

@nounoursnoir那是因爲當你解引用數組時,它衰減到一個指向它的第一個元素的指針,並且取消引用那個給你*值的指針*指針指向。在你的情況下,它是一個'char'類型的字符。所以'sizeof(* str)'等於'sizeof(str [0])',它等於'sizeof(char)',它被指定爲始終爲'1'。 –

1
char str[]="1234" 

的大小爲5,因爲它是str[5] = {'1','2','3','4',0}的語法糖。

char str[5]; 

的大小爲5,因爲它是sizeof(char)*5

char *str = ...; 

具有大小爲8,因爲它是一個指針。

0

比較這些代碼片段

char str2[] = "1234"; 
char *p = str2; 

char *p = malloc(sizeof(char) * 5); 

它們有以下共同點:指針p指向分配內存的第一個字節。在第一種情況下,內存由編譯器分配,而在第二種情況下,內存由您在堆中分配。

爲了使其更清楚,最好在C++中考慮類似的代碼片段。他們會像

char str2[] = "1234"; 
char *p = str2; 

char *p = new char[5]; 

,你將有

的第一個代碼段

printf("%zu\n", sizeof(str2)); // 5 
printf("%zu\n", sizeof(p)); // 8 

的第二代碼片段

printf("%zu\n", sizeof(char[5])); // 5 
printf("%zu\n", sizeof(p)); // 8 

區別在於,在第二種情況下,我們沒有創建動態數組的名稱。所以你必須使用sizeof(char[5])而不是sizeof(array_name)

-1

我認爲你的編譯器是64位,它總是分配字符*的固定尺寸,其是8

相關問題