0

在 C 中分配字符串的正确形式是什么?

char *sample;

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

或者

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

为什么占用 1char*个字节时char占用 4 个字节?

4

9 回答 9

6

假设目标是存储一串length字符,正确的分配是:

sample = malloc(length + 1);

笔记:

  1. 不要使用sizeof (char),因为它总是 1 它不会增加任何价值。
  2. 记住终止符,我假设(基于名称)length是字符串可见字符的长度,即strlen()will的返回length
  3. 我知道你没有,但值得指出的是,也不应该对 from 的返回值进行malloc()强制转换。

更大的原因char *是它是指针类型,并且指针几乎总是大于单个字符。在许多系统上(比如你的系统,似乎)它们是 32 位的,而字符只有 8 位。因为指针需要能够表示机器内存中的任何地址,所以需要更大的大小。在 64 位计算机上,指针通常是 64 位,即 8 个字符。

于 2012-12-06T11:11:18.877 回答
2

为什么 char 占用 1 个字节时 char* 占用 4 个字节?

因为您在 32 位系统上,这意味着指针占用四个字节;char*是一个指针。

char总是只占用一个字节,所以你不需要乘以sizeof(char)

sample = malloc (length);

我假设length已经为空终止填充了它。

于 2012-12-06T11:12:26.003 回答
1
sample = malloc(length);

是对的

char*是一个指针,一个指针使用 4 个字节(比如在 32 位平台上)

char是一个 char,一个 char 使用 1 个字节

于 2012-12-06T11:10:06.630 回答
1
sample = malloc ( length * sizeof(char) );

如果您想为length字符数分配内存,第一个是正确的。

char*是指针类型,在您的平台上恰好是 4 个字节。所以sizeof(char*)返回 4。

sizeof(char)始终为 1 并且 smae 由 C 标准保证。

于 2012-12-06T11:10:47.020 回答
1

在给定的情况下,您正在做两件事:

在第一种情况下:sample = malloc ( length * sizeof(char) );

您正在分配length乘以1 字节char的类型大小

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

您正在分配length乘以 您机器上char4字节的指针大小。

考虑一下,虽然情况 1 保持不变,但在第二种情况下,大小是可变的。

于 2012-12-06T11:14:05.750 回答
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
于 2012-12-06T11:35:00.160 回答
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的数量和大小,而只需要总大小.

于 2012-12-06T11:36:16.983 回答
0

对于任何类型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 )时才需要括号。 &*intchar *

于 2012-12-06T11:59:50.230 回答
0

请访问此链接https://www.codesdope.com/c-dynamic-memory/了解它如何在运行时动态分配内存。了解malloc的概念以及它如何将内存量分配给变量可能会有所帮助。

在你的例子中;

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

在这里,您为示例声明了一个指向字符的指针,而没有声明它需要多少内存。在下一行中,length * sizeof(char) bytes内存分配给 sample 的地址, (char*) 是将 malloc 返回的指针类型转换为字符。

于 2019-05-13T13:54:38.610 回答