据我所知,malloc函数接受一个变量并按要求分配内存。在这种情况下,它会要求编译器准备内存以适应20个双变量的等价。我的理解方式是否正确,为什么必须使用它?
double *q;
q=(double *)malloc(20*sizeof(double));
for (i=0;i<20; i++)
{
*(q+i)= (double) rand();
}
答案 0 :(得分:6)
在以下情况下您不必使用malloc()
:
请注意malloc()
在运行时分配内存,而不是在编译时分配内存。编译器仅涉及确保调用正确函数的程度;它是malloc()
进行分配。
你的例子提到了“十个整数的等价”。 20 double
占据与10 int
相同的空间很少。通常,10 double
将占用与int
相同的空格(当sizeof(int) == 4
和sizeof(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 leaks和dangling 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
}