【问题标题】:char * buf = malloc(sizeof (char *) * 16) vs char buf[ sizeof (char *) * 16]char * buf = malloc(sizeof (char *) * 16) vs char buf[ sizeof (char *) * 16]
【发布时间】:2012-03-01 04:52:32
【问题描述】:

我正在阅读一个 C 代码

char * buf = malloc(sizeof (char *) * 16)

而不是

char buf[sizeof (char *) * 16]

有什么区别?好吧,我认为第一个表达式是不必要的,如果没有调用realloc(),还是我想错了?

【问题讨论】:

  • 这是自动数组和动态数组的区别。一种位于自动存储中,您不必解除分配,另一种位于动态存储中,您必须解除分配。喜欢第一个。
  • 第一行动态分配一个字节数组(字符),只要指针的大小(可能是 4 个字节)乘以 16 = 64 个字节。这没有任何意义。第二行静态分配一个字节数组(字符),只要指针的大小乘以 16 = 64 字节。这也没有任何意义。
  • donwvotes - 可以解释一下吗?

标签: c arrays memory-management


【解决方案1】:

char buf[sizeof(char*)*16]是自动分配的数组,一般是栈。只要 buf 在范围内,并且有足够的堆栈空间,它就有效。

malloc 从某个堆中分配内存。在此内存为free()ed 之前有效。通常,可用的堆要多得多。

【讨论】:

    【解决方案2】:

    Yann 的注释是正确的。

    这似乎是一个指针数组。因为它分配的内存是 char 指针大小的 16 倍。指针大小在不同的系统上会有所不同。有些指针是 32 位(4 字节),有些是 64 位(8 字节)。

    char buf[sizeof(char *) * 16] 不是一个指针数组,它是一个字符数组,其元素的大小等于 char 指针的大小乘以 16。

    【讨论】:

      【解决方案3】:

      动态数组

      第一个是dynamic array。表达式char * buf = malloc(sizeof (char *) * 16) 将元素存储在内存中(malloc 基本上用于内存分配)。使用它的优点是,您可以重新分配它,即在运行时调整它的大小。但是,您可能必须在每次添加新元素时分配新内存。这是一个例子:

      #include <stdlib.h>
      #include <stdio.h>
      #include <conio.h>
      int main() {
        int* array;
        int n, i;
        printf("Enter the number of elements: ");
        scanf("%d", &n);
        array = malloc(n*sizeof(int));
        for (i=0; i<n; i++) {
        printf("Enter number %d: ", i);
        scanf("%d", &array[i]);
        }
        printf("\nThe Dynamic Array is: \n");
        for (i=0; i<n; i++) {
        printf("The value of %d is %d\n", i, array[i]);
        }
        printf("Size= %d\n", i);
        getch();
        return 0;
      }
      

      输出:

      自动(静态?)数组

      第二个表达式char buf[sizeof (char *) * 16] 只是声明了一个无聊的自动数组。它的大小是静态的。没有动态调整大小、重新分配等。

      注意:对于malloc 之前的类型转换表示歉意。如果你做错了什么,对 malloc 的返回值进行类型转换将导致编译器不给出错误。这之后可能会出现未定义的运行时错误和调试地狱。始终避免对malloc 的结果进行类型转换。谢谢@Lundin。

      【讨论】:

      • -1 用于对 malloc 的结果进行类型转换。请参阅C FAQthis post。请更正此问题,我将删除反对票。
      • @Lundin 对此感到抱歉。感谢您的帖子,目前从我自己过去的 C 代码库中删除 malloc 之前的所有类型转换。 :)
      • 如果您不进行类型转换,有些编译器会抱怨,例如mbed 的编译器,您无法调整设置:/
      【解决方案4】:

      主要区别在于,如果这是代码在函数中,返回后仍然可以使用前者中声明的指针。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-29
        • 2017-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-27
        • 2021-12-17
        • 1970-01-01
        相关资源
        最近更新 更多