为什么 str[5]、str[] = "1234" 和 str = malloc(5) 有不同的大小?
Why do str[5], str[] = "1234" and str = malloc(5) have different sizes?
请考虑以下声明:
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];
分配5个字节的内存给str
,那么str
的大小就是5个字节。但是当我用malloc
给char *str
分配5个字节时,str
的大小还是8个字节,也就是一个指针的大小。我希望 str3
的大小与我用 malloc
.
分配给它的内存量相对应
为什么我错了?
TL;DR -- Arrays are not pointers and vice-versa
在您的代码中,str1
和 str2
是 "arrays",而 str3
是 "pointer"。它们的尺寸是根据各自的类型印刷的。
根据定义,str1
有 5 个 char
元素。
str2
也有 5 个 char
元素,初始值设定项 + 空终止符。
str3
是一个指针,所以sizeof(str3)
=== sizeof(char *)
[注意:这取决于你的环境,它不是固定的,最常见的值是8(64 位 rach)和 4(32 位 arch)]
FWIW,使用 %zu
打印 sizeof
运算符的输出,因为它是 size_t
.
类型
获取指针的大小得到的是指针的大小,而不是它指向的内容。你得到大小 8
意味着你在一个 64 位系统上,其中指针是 64 位(8 字节)。
数组是固定大小的内存块,在其上使用 sizeof
运算符将为您提供该块的大小。
char str[]="1234"
大小为 5,因为它是 str[5] = {'1','2','3','4',0}
.
的语法糖
char str[5];
sizeof(char)*5
尺寸为 5。
和
char *str = ...;
大小为 8,因为它是一个指针。
比较这些代码片段
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 )
.
请考虑以下声明:
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];
分配5个字节的内存给str
,那么str
的大小就是5个字节。但是当我用malloc
给char *str
分配5个字节时,str
的大小还是8个字节,也就是一个指针的大小。我希望 str3
的大小与我用 malloc
.
为什么我错了?
TL;DR -- Arrays are not pointers and vice-versa
在您的代码中,str1
和 str2
是 "arrays",而 str3
是 "pointer"。它们的尺寸是根据各自的类型印刷的。
-
根据定义,
str1
有 5 个char
元素。str2
也有 5 个char
元素,初始值设定项 + 空终止符。str3
是一个指针,所以sizeof(str3)
===sizeof(char *)
[注意:这取决于你的环境,它不是固定的,最常见的值是8(64 位 rach)和 4(32 位 arch)]
FWIW,使用 %zu
打印 sizeof
运算符的输出,因为它是 size_t
.
获取指针的大小得到的是指针的大小,而不是它指向的内容。你得到大小 8
意味着你在一个 64 位系统上,其中指针是 64 位(8 字节)。
数组是固定大小的内存块,在其上使用 sizeof
运算符将为您提供该块的大小。
char str[]="1234"
大小为 5,因为它是 str[5] = {'1','2','3','4',0}
.
char str[5];
sizeof(char)*5
尺寸为 5。
和
char *str = ...;
大小为 8,因为它是一个指针。
比较这些代码片段
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 )
.