分配大小为 char * 的内存有什么作用?

What does allocating memory of size char * do?

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

这段代码为变量str分配了5个连续的内存槽,它的类型是char *

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

这应该分配 5 倍于 char 数组的内存。但是由于 char 数组在我们声明之前没有大小,所以这个语句实际上做了什么?

第一部分

This code allocates 5 "consecutive slots of memory" to the variable str, which is of type char *.

不,不是真的。确切地说,如果它成功,它 returns 一个指向内存块的指针,该内存块大到足以容纳 5 chars,这是提供给 malloc() 的大小。在C中,sizeof(char)保证是1,所以是5个字节。

相关,C11,章节 §7.22.3.4

The malloc() function allocates space for an object whose size is specified by size and whose value is indeterminate.

因此,没有 "consecutive block" 本身,它是具有指定大小的内存区域(space for "an" object)。

在后面的例子中,大小是char *,一个指针。根据您的环境,字节数将为 5 * sizeof (char *),其中 sizeof(char *) 可以是 4 或 8 或其他任何值。

注意,这两种情况,返回的指针都是void *.

类型

还要注意这个

用于提供 malloc() 参数大小的数据类型对返回的指针没有附件或影响,它 用于计算 size 传递给 malloc()

例如,如果恰好对于某个平台,sizeof(int) === sizeof(float),那么,我们可以写

    int *intPtr = malloc(sizeof *fltPtr);   //int pointer
    float *fltPtr = malloc(sizeof *intPtr); // float pointer

考虑到成功,我们可以完美地利用这两个指针。

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

它分配了足够的内存来存储5个指向char的指针(5个地址)。它不是分配内存来存储数组,而是分配它们的地址

以下代码

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

5 类型的连续元素分配内存 char *,即:指向 char.[=14= 的指针]

然后您可以分配 N 个类型为 char 的连续元素,并将它们的地址分配给这些指针:

for (int i = 0; i < 5; i++)
   str[i] = malloc(sizeof(char) * N));

第二部分实际上分配了5次char指针,而不是数组

// main.c

#include <stdio.h>
int main()
{
    printf("%u\n", sizeof(char *));
}

如果你在32位环境下编译上面的代码,这段代码会打印4。在64位环境下,这段代码会打印8。(你可以在64位环境下自行测试,方法如下以下 如何测试 中描述的步骤。)

因此,根据您的环境,char *str = malloc(sizeof(char *) * 5); 分配 2040 字节的内存,由 str 指向。因此,如果您打算在 str 中存储一个 c 类型字符串,您将能够存储 1939 个字符。


如何测试

我在 64 位 Ubuntu 14.04。在 64 位环境中,您可以使用以下编译器选项测试上述示例代码。

$ gcc -m32 -o out32 main.c
$ ./out32
4
$ gcc -o out64 main.c
$ ./out64
8

如果您收到错误提示sys/cdefs.h: No such file or directory,请安装以下软件包。

$ sudo apt install libx32gcc-4.8-dev
$ sudo apt install libc6-dev-i386

(从 this article 获得所需的包名称)