为什么要使用malloc?

时间:2012-12-15 08:17:45

标签: c variables memory memory-management malloc

据我所知,malloc函数接受一个变量并按要求分配内存。在这种情况下,它会要求编译器准备内存以适应20个双变量的等价。我的理解方式是否正确,为什么必须使用它?

double *q;

q=(double *)malloc(20*sizeof(double));

for (i=0;i<20; i++)
{
    *(q+i)= (double) rand();
}

6 个答案:

答案 0 :(得分:6)

在以下情况下您不必使用malloc()

  1. 在编译时已知大小,如您的示例所示。
  2. 您正在使用支持VLA(可变长度阵列)的C99或C2011。
  3. 请注意malloc()在运行时分配内存,而不是在编译时分配内存。编译器仅涉及确保调用正确函数的程度;它是malloc()进行分配。

    你的例子提到了“十个整数的等价”。 20 double占据与10 int相同的空间很少。通常,10 double将占用与int相同的空格(当sizeof(int) == 4sizeof(double) == 8时,这是一个非常常见的设置。)

答案 1 :(得分:4)

它用于在运行时而不是编译时分配内存。因此,如果您的数据阵列基于来自用户,数据库,文件等的某种输入,则必须在知道所需大小后使用malloc

变量q是一个指针,意味着它在内存中存储一​​个地址。 malloc要求系统创建一段内存并返回该部分内存的地址,该地址存储在q中。因此q指向您请求的内存的起始位置。

必须注意不要无意中改变q。例如,如果您这样做:

q = (double *)malloc(20*sizeof(double));
q = (double *)malloc(10*sizeof(double));

您将无法访问20 double的第一部分并引入内存泄漏。

答案 2 :(得分:3)

当你使用malloc时,你问系统“嘿,我想要这么多字节的内存”然后他要么说“对不起,我全力以赴”或“好吧!这是一个地址你想要的记忆。不要失去它。“

将大数据集放在堆中(malloc从中获取内存)和指向堆栈上的内存的指针(执行代码的位置)通常是个好主意。这在内存有限的嵌入式平台上变得更加重要。您必须决定如何在堆栈和堆之间分配物理内存。堆栈太多,您无法动态分配大量内存。堆栈太少,您可以直接调用它(也称为堆栈溢出:P)

答案 3 :(得分:1)

在您的示例中,您可以在没有double q[20];的情况下声明malloc并且它可以正常工作。

malloc是获取动态分配内存的标准方法(malloc通常构建在低级内存采集原语之上,如Linux上的mmap

您希望获得动态分配的内存资源,特别是当分配的内容(此处为您的q指针)的大小取决于运行时参数(例如,取决于输入)时。糟糕的选择是静态分配所有内容,但是数据的静态大小是一个强大的内置限制,你不喜欢这样。

动态资源分配使您可以在便宜的平板电脑(具有半千兆字节的RAM)和昂贵的超级计算机(具有太字节的RAM)上运行相同的程序。您可以分配不同大小的数据。

不要忘记测试malloc的结果;它可以通过返回NULL失败。至少,代码:

 int* q = malloc (10*sizeof(int));
 if (!q) {
    perror("q allocation failed");
    exit(EXIT_FAILURE);
 };

始终初始化 malloc - 内存(您可能更喜欢使用calloc来清除已分配的内存。)

不要忘记稍后free malloc - 内存。在Linux上,了解如何使用valgrind。害怕memory leaksdangling pointers。认识到某些数据的活跃性是整个程序的非模块化属性。阅读garbage collection!,并考虑使用Boehm's conservative garbage collector(通过调用GC_malloc代替malloc)。

答案 4 :(得分:1)

正如其他人所说,malloc用于分配内存。重要的是要注意malloc将从堆中分配内存,因此内存是持久的,直到它为free'd。否则,如果没有malloc,声明类似double vals[20]的内容将在堆栈上分配内存。退出该函数时,该内存将从堆栈中弹出。

例如,假设您处于一个函数中,并且您不关心值的持久性。那么以下是合适的:

void some_function() {
    double vals[20];
    for(int i = 0; i < 20; i++) {
        vals[i] = (double)rand();
    }
}

现在,如果你有一些全局结构或存储数据的东西,它的生命周期比只有函数的生命周期长,那么需要使用malloc从堆中分配内存(或者,你可以将它声明为全局变量,内存将为你预分配。)

答案 5 :(得分:0)

您使用malloc()C中动态分配内存。 (在run time分配内存) 您使用它是因为有时您不知道在编写程序时将使用多少内存。 当您知道数组在编译时将保留许多元素时,您不必使用它。

另一个重要的事情要注意,如果你想从一个函数返回一个数组,你会想要在堆栈函数内返回一个不是定义的数组。相反,您需要动态分配一个数组(在上)并返回指向此块的指针:

int *returnArray(int n) 
{
    int i;
    int *arr = (int *)malloc(sizeof(int) * n);
    if (arr == NULL) 
    {
        return NULL; 
    }

    //...
    //fill the array or manipulate it
    //... 

    return arr; //return the pointer
}