在 C 中分配字符串的正确形式是什么?
char *sample;
sample = malloc ( length * sizeof(char) );
或者
sample = malloc ( length * sizeof(char*) );
为什么占用 1char*
个字节时char
占用 4 个字节?
在 C 中分配字符串的正确形式是什么?
char *sample;
sample = malloc ( length * sizeof(char) );
或者
sample = malloc ( length * sizeof(char*) );
为什么占用 1char*
个字节时char
占用 4 个字节?
假设目标是存储一串length
字符,正确的分配是:
sample = malloc(length + 1);
笔记:
sizeof (char)
,因为它总是 1 它不会增加任何价值。length
是字符串可见字符的长度,即strlen()
will的返回length
。malloc()
强制转换。更大的原因char *
是它是指针类型,并且指针几乎总是大于单个字符。在许多系统上(比如你的系统,似乎)它们是 32 位的,而字符只有 8 位。因为指针需要能够表示机器内存中的任何地址,所以需要更大的大小。在 64 位计算机上,指针通常是 64 位,即 8 个字符。
为什么 char 占用 1 个字节时 char* 占用 4 个字节?
因为您在 32 位系统上,这意味着指针占用四个字节;char*
是一个指针。
char
总是只占用一个字节,所以你不需要乘以sizeof(char)
:
sample = malloc (length);
我假设length
已经为空终止填充了它。
sample = malloc(length);
是对的
char*
是一个指针,一个指针使用 4 个字节(比如在 32 位平台上)
char
是一个 char,一个 char 使用 1 个字节
sample = malloc ( length * sizeof(char) );
如果您想为length
字符数分配内存,第一个是正确的。
char*
是指针类型,在您的平台上恰好是 4 个字节。所以sizeof(char*)
返回 4。
但sizeof(char)
始终为 1 并且 smae 由 C 标准保证。
在给定的情况下,您正在做两件事:
在第一种情况下:sample = malloc ( length * sizeof(char) );
您正在分配length
乘以1 字节char
的类型大小
而在第二种情况下: sample = malloc ( length * sizeof(char*) );
您正在分配length
乘以
您机器上char
4字节的指针大小。
考虑一下,虽然情况 1 保持不变,但在第二种情况下,大小是可变的。
在您的情况下,您想要分配一个长度字符数组。您将存储sample
一个指向数组的指针,该数组length
的大小是您所指向的大小的倍数。sizeof(char*)
是指向 的指针的大小char
。不是a的大小char
。
一个好的做法是
sample = malloc(length * sizeof(*sample));
使用它,您将保留要指向的大小的长度时间。这使您能够随时更改数据类型,只需将 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*)
是指针的大小,它与分配的缓冲区需要的大小完全无关。所以绝对不要用那个。
我的第一个片段在 IMO 中对于字符串操作代码来说已经足够好了。C 程序员知道 C 中的内存和字符串长度都以sizeof(char)
. 没有必要在其中放入每个人都知道的转换因子1
。
我的第二个片段是写分配的一种真正方法。因此,如果您希望所有分配看起来一致,那么字符串分配也应该使用它。我可以想到两个可能的原因来使您的所有分配看起来一致(IMO 都相当弱,但实际上并没有错):
length
不再以字节为单位而是以宽字符为单位时,一致的形式会提醒您正确分配。使用sizeof(*sample)
作为一致形式意味着您根本不需要更改该行代码,假设您在更新类型的sample
同时作为length
测量单位。其他选项包括:
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
是一个类似or的运算符,而不是库函数;仅当操作数是类型名称(如or )时才需要括号。 &
*
int
char *
请访问此链接https://www.codesdope.com/c-dynamic-memory/了解它如何在运行时动态分配内存。了解malloc的概念以及它如何将内存量分配给变量可能会有所帮助。
在你的例子中;
char *sample;
sample = malloc ( length * sizeof(char) );
在这里,您为示例声明了一个指向字符的指针,而没有声明它需要多少内存。在下一行中,length * sizeof(char) bytes内存分配给 sample 的地址, (char*) 是将 malloc 返回的指针类型转换为字符。