1

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

double *q;

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

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

6 回答 6

6

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

  1. 如您的示例所示,大小在编译时是已知的。
  2. 您正在使用具有 VLA(可变长度数组)支持的 C99 或 C2011。

请注意,malloc()在运行时分配内存,而不是在编译时。编译器仅在确保调用正确函数的范围内参与;就是malloc()这样分配的。

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

于 2012-12-15T08:25:07.603 回答
4

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

该变量q是一个指针,这意味着它在内存中存储了一个地址。malloc要求系统创建一段内存并返回该段内存的地址,该地址存储在q. 所以q指向你请求的内存的起始位置。

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

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

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

于 2012-12-15T08:20:05.907 回答
3

当您使用时,malloc您是在询问系统“嘿,我想要这么多字节的内存”,然后他会说“对不起,我已经用完了”或“好的!这是您想要的内存的地址。不要”不要失去它”。

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

于 2012-12-15T08:38:49.523 回答
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 从堆中分配内存(或者,您可以将其声明为全局变量,并且内存将为您预先分配)。

于 2012-12-15T08:34:42.847 回答
1

在您的示例中,您可以在double q[20];没有 the 的情况下声明malloc它会起作用。

malloc是获取动态分配内存的标准方法(通常构建在 Linuxmalloc等低级内存获取原语之上)。mmap

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

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

不要忘记测试结果malloc;它可能会因返回 NULL 而失败。至少,代码:

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

始终初始化 malloc-ed 内存(您可能更喜欢使用calloc将分配的内存归零)。

不要忘记稍后freemalloc-ed 内存。在 Linux 上,了解如何使用valgrind。害怕内存泄漏悬空指针。认识到某些数据的活跃性是整个程序的非模块化属性。阅读垃圾收集!,并考虑使用Boehm 的保守垃圾收集器(通过调用GC_malloc而不是malloc)。

于 2012-12-15T08:22:16.853 回答
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
}
于 2012-12-15T08:22:41.230 回答