Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
何时以及为什么使用malloc?_C_Malloc_Dynamic Memory Allocation - Fatal编程技术网

何时以及为什么使用malloc?

何时以及为什么使用malloc?,c,malloc,dynamic-memory-allocation,C,Malloc,Dynamic Memory Allocation,嗯,我无法理解何时以及为什么需要使用malloc分配内存 这是我的密码: #include <stdlib.h> int main(int argc, const char *argv[]) { typedef struct { char *name; char *sex; int age; } student; //Now I can do two things student p; //or student *ptr =

嗯,我无法理解何时以及为什么需要使用
malloc
分配内存

这是我的密码:

#include <stdlib.h>

int main(int argc, const char *argv[]) {

  typedef struct {
    char *name;
    char *sex;
    int age;
  } student;


  //Now I can do two things
  student p;

  //or
  student *ptr = (student *)malloc(sizeof(student));

  return 0;
}
#包括
int main(int argc,const char*argv[]{
类型定义结构{
字符*名称;
性别;
智力年龄;
}学生;
//现在我可以做两件事
学生p;
//或
学生*ptr=(学生*)malloc(学生人数);
返回0;
}

当我可以使用
student p时,为什么需要分配内存

当您需要分配必须存在于当前块的执行生命周期之外的对象时(返回时的复制也会很昂贵),或者如果您需要分配大于该堆栈大小的内存时(即:3mb本地堆栈数组是个坏主意),您可以使用
malloc


在C99引入VLA之前,您还需要它来执行动态大小数组的分配,但是,创建树、列表和队列等动态数据结构需要它,许多系统都使用它。可能还有更多的原因,这些只是少数。

malloc
用于动态内存分配。如前所述,它是动态分配,即在运行时分配内存。例如,当您不知道编译时的内存量时

有一个例子可以说明这一点。假设你知道最多有20名学生。因此,您可以创建一个包含静态20个元素的数组。您的阵列最多可容纳20名学员。但是如果你不知道学生的数量呢?假设第一个输入是学生人数。可能是10,20,50或者其他什么。现在,您将获取input n=运行时的学生数量,并使用
malloc
动态分配大量内存

这只是一个例子。在很多情况下都需要动态分配


查看手册页。

malloc=内存分配

如果您使用过其他编程语言,则可能使用了
new
关键字

Malloc在C中做了完全相同的事情。它接受一个参数,需要分配的内存大小,并返回一个指针变量,该变量指向在内存中创建的整个内存块的第一个内存块。范例-

int *p = malloc(sizeof(*p)*10);
现在,
*p
将指向内存中保留的连续10个整数块中的第一个块

可以使用
++
--
操作符遍历每个块


一切都好。

在这个例子中,它看起来确实毫无用处。但现在假设您使用的是套接字或文件IO,并且必须从可变长度读取数据包,您只能在运行时阻止这些数据包。或者在使用套接字时,每个客户端连接都需要服务器上的一些存储。你可以做一个静态数组,但是这会给你一个客户端限制,这将在编译过程中起到威慑作用。

< p>稍微扩展例子的结构,考虑一下:

#include <stdio.h>

int main(int argc, const char *argv[]) {

typedef struct {
 char* name;
 char* sex;
 char* insurace;
 int age;
 int yearInSchool;
 float tuitionDue;
}student;


//Now I can do two things
student p;

//or
student *p = malloc(sizeof *p);

}
#包括
int main(int argc,const char*argv[]{
类型定义结构{
字符*名称;
性别;
char*保险公司;
智力年龄;
在校国际年;
浮动学费到期;
}学生;
//现在我可以做两件事
学生p;
//或
学生*p=malloc(sizeof*p);
}
C是一种隐式传递值而不是引用的语言。在本例中,如果我们将“p”传递给一个函数对其执行一些操作,那么我们将创建整个结构的副本。这会使用额外的内存(特定结构所需的总空间),速度较慢,并且可能无法很好地扩展(一分钟内会有更多)。但是,通过*p,我们不会通过整个结构。我们只在内存中传递引用此结构的地址。传递的数据量更小(指针大小),因此操作更快


现在,知道了这一点,想象一下一个程序(比如学生信息系统),它必须创建和管理数千甚至数万条记录。如果按值传递整个结构,则对一组数据进行操作所需的时间将比只传递指向每个记录的指针所需的时间更长。

让我们尝试从不同方面来解决这个问题

大小
malloc
允许您分配比仅使用
student p分配的内存空间大得多的内存空间
intx[n]。原因是
malloc
在堆上分配空间,而另一个在堆栈上分配空间

C编程语言静态、自动或动态地管理内存。静态持续时间变量通常与程序的可执行代码一起分配到主内存中,并在程序的生命周期内保持不变;自动持续时间变量在堆栈上分配,并在调用和返回函数时来来去去。对于静态持续时间和自动持续时间变量,分配的大小必须是编译时常量(可变长度自动数组的情况除外[5])。如果直到运行时才知道所需的大小(例如,如果从用户或磁盘文件读取任意大小的数据),则使用固定大小的数据对象是不够的。()

范围 通常,声明的变量将在声明它的块之后被删除/释放(它们在堆栈上声明)。另一方面,使用
malloc
分配内存的变量保留到手动释放时

这也意味着您不可能在函数中创建变量/数组/结构并返回其地址(因为它所指向的内存可能会被释放)。编译器还试图通过发出以下警告来警告您:

警告-返回与局部变量“matches”关联的堆栈内存地址

欲知详情

更改大小(
realloc
) 正如你可能已经猜到的,它