【问题标题】:What does allocating memory of size char * do?分配大小为 char * 的内存有什么作用?
【发布时间】:2017-10-26 04:10:22
【问题描述】:
char    *str;
str = malloc(sizeof(char) * 5);

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

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

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

【问题讨论】:

  • * 表示指针不是数组。它为 chars 分配一个包含 5 个指针的块
  • char * 本身就是一个数据类型(pointer-to-char),所以第二条语句分配一个内存块来存储 5 个 char-pointers。
  • 顺便说一句,在我的系统上 (Linux/x86-64) sizeof(char*) 是 8(就像任何指针的大小一样)

标签: c pointers malloc dynamic-memory-allocation allocation


【解决方案1】:

第一部分

这段代码为str类型的变量char *分配了5个“连续的内存槽”。

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

相关,C11,第 7.22.3.4 章

malloc() 函数为大小由size 指定的对象分配空间,并且 其值是不确定的。

因此,不存在这样的“连续块”,它是一个具有指定大小的内存区域(“一个”对象的空间)。

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

注意,两种情况,返回的指针都是void *类型。


还要注意这一点

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

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

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

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

【讨论】:

    【解决方案2】:

    以下代码

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

    char * 类型的5-连续元素分配内存,即:指向字符的指针

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

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

    【讨论】:

    • 如果令人困惑,请解释原因
    【解决方案3】:
    char    *str;
    str = malloc(sizeof(char *) * 5);
    

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:
        // main.c
        
        #include <stdio.h>
        int main()
        {
            printf("%u\n", sizeof(char *));
        }
        

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

        因此,根据您的环境,char *str = malloc(sizeof(char *) * 5); 分配str 指向的2040 字节内存。因此,如果您打算将 c 类型字符串存储在 str 中,您将能够存储 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 获得所需的包名称)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-10-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-02-07
          • 2011-06-08
          • 2014-01-11
          • 2020-03-04
          相关资源
          最近更新 更多