据我所知,malloc函数接受一个变量并按要求分配内存。在这种情况下,它将要求编译器准备内存,以适应二十个双变量的等价性。我理解它的方式正确吗?为什么必须使用它?
double *q;
q=(double *)malloc(20*sizeof(double));
for (i=0;i<20; i++)
{
*(q+i)= (double) rand();
}
时不必使用malloc()
- 大小在编译时是已知的,如您的示例所示
- 您使用的C99或C2011支持VLA(可变长度阵列)
请注意,malloc()
在运行时分配内存,而不是在编译时。编译器只在确保调用正确函数的情况下才参与;是CCD_ 3进行分配。
你的例子提到"十个整数等价"。很少有20个double
与10个int
占据相同的空间。通常,10个double
将占用与20个int
相同的空间(当sizeof(int) == 4
和sizeof(double) == 8
时,这是一种非常常见的设置)。
它用于在运行时而不是编译时分配内存。因此,如果您的数据数组基于来自用户、数据库、文件等的某种输入,那么一旦知道所需的大小,就必须使用malloc
。
变量q
是一个指针,意味着它在内存中存储一个地址。malloc
要求系统创建一段存储器,并返回存储在q
中的该段存储器的地址。因此q
指向您请求的内存的起始位置。
必须注意不要无意中更改q
。例如,如果你这样做了:
q = (double *)malloc(20*sizeof(double));
q = (double *)malloc(10*sizeof(double));
您将无法访问20个double
的第一部分,并导致内存泄漏。
当你使用malloc
时,你问系统"嘿,我想要这么多字节的内存",然后他会说"对不起,我用完了"或"好吧!这是你想要的内存地址。不要丢失"。
通常,最好将大数据集放在堆中(malloc
从中获取内存),并在堆栈上指向该内存(代码执行的地方)。这在内存有限的嵌入式平台上变得更加重要。您必须决定如何在堆栈和堆之间分配物理内存。堆栈太多,无法动态分配太多内存。堆栈太少,您可以直接调用函数(也称为堆栈溢出:P)
正如其他人所说,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从堆中分配内存(或者,你可以将其声明为全局变量,内存将为你预先分配)。
在您的示例中,您可以在没有malloc
的情况下声明double q[20];
,它会起作用。
malloc
是获得动态分配内存的标准方法(malloc
通常构建在Linux上的mmap
等低级内存获取原语之上)。
您希望获得动态分配的内存资源,尤其是当分配的东西(这里是q
指针)的大小取决于运行时参数(例如,取决于输入)时。糟糕的选择是静态分配所有数据,但数据的静态大小是一个强大的内置限制,你不喜欢这样。
动态资源分配使您能够在廉价的平板电脑(具有半GB的RAM)和昂贵的超级计算机(具有TB的RAM)上运行相同的程序。您可以分配不同大小的数据。
不要忘记测试malloc
的结果;它可能会返回NULL而失败。至少,代码:
int* q = malloc (10*sizeof(int));
if (!q) {
perror("q allocation failed");
exit(EXIT_FAILURE);
};
并且总是初始化malloc
的内存(您可以更喜欢使用calloc
,它将分配的内存归零)。
不要忘记稍后malloc()
0的malloc
内存。在Linux上,学习如何使用valgrind。要害怕内存泄漏和悬空指针。认识到某些数据的活跃性是整个程序的非模块化特性。阅读有关垃圾收集的内容!,并考虑使用Boehm的保守垃圾收集器(通过调用GC_malloc
而不是malloc
)。
使用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
}