菜单
×
   ❮   
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE
     ❯   

C 内存分配


保留内存的过程称为分配。分配内存的方式取决于内存的类型。

C 语言有两种内存类型:静态内存和动态内存。


静态内存

静态内存是在程序运行**前**为变量保留的内存。静态内存分配也称为*编译时*内存分配。

当程序编译时,C 语言会自动为每个变量分配内存。

例如,如果您创建一个包含 20 名学生(例如用于暑期学期)的整数数组,C 语言将为 20 个元素保留空间,通常是 80 字节的内存(20 * 4)。

示例

int students[20];
printf("%lu", sizeof(students)); // 80 字节
自己动手试一试 »

但是当学期开始时,发现只有 12 名学生入学。那么您就浪费了 8 个未使用元素的空间。

由于您无法更改数组的大小,因此您将留下不必要的保留内存。

请注意,程序仍将运行,并且不会以任何方式损坏。但是,如果您的程序包含大量此类代码,它可能比最佳状态运行得慢。

如果您希望更好地控制已分配的内存,请查看下面的动态内存。


动态内存

动态内存是在程序开始运行**后**分配的内存。动态内存分配也可以称为*运行时*内存分配。

与静态内存不同,您可以完全控制在任何时候使用了多少内存。您可以编写代码来确定您需要多少内存并进行分配。

动态内存不属于变量,它只能通过指针访问。

要分配动态内存,可以使用 malloc()calloc() 函数。必须包含 <stdlib.h> 头文件才能使用它们。malloc()calloc() 函数分配一些内存并返回其地址的指针。

int *ptr1 = malloc(size);
int *ptr2 = calloc(amount, size);

malloc() 函数有一个参数,size,它指定要分配的内存量,以字节为单位。

calloc() 函数有两个参数

  • amount - 指定要分配的项目数量
  • size - 指定每个项目的大小,以字节为单位

注意:malloc() 分配的内存中的数据是不可预测的。为避免意外值,请务必在读取内存之前写入一些内容。

malloc() 不同,calloc() 函数将零写入所有已分配的内存。然而,这使得 calloc() 的效率略低。

为数据类型分配正确内存量的最佳方法是使用 sizeof 运算符

int *ptr1, *ptr2;
ptr1 = malloc(sizeof(*ptr1));
ptr2 = calloc(1, sizeof(*ptr2));

小心 sizeof(*ptr1) 告诉 C 语言测量地址处数据的大小。如果您忘记 * 而改为写入 sizeof(ptr1),它将测量指针本身的大小,这通常是存储内存地址所需的 8 个字节。

注意:sizeof 运算符无法测量分配了多少动态内存。测量动态内存时,它只告诉您内存*数据类型*的大小。例如,如果您为 5 个 float 值保留空间,sizeof 运算符将返回 4,这是一个 float 值所需的字节数。

让我们使用动态内存来改进上面的学生示例。

如前所述,我们不能使用 sizeof 来测量分配了多少内存,我们必须通过将项目数量乘以数据类型的大小来计算。

示例

int *students;
int numStudents = 12;
students = calloc(numStudents, sizeof(*students));
printf("%d", numStudents * sizeof(*students)); // 48 字节
自己动手试一试 »

注意

在使用动态内存分配时,您还应该**检查错误**并在程序结束时**释放内存**。您将在下一章中了解更多信息。


栈内存

为了完整起见,值得一提的是栈内存。栈内存是一种动态内存,它为函数内部声明的变量保留。在函数内部声明的变量使用栈内存而不是静态内存。

当函数被调用时,会为函数中的变量分配栈内存。当函数返回时,栈内存被释放。

了解栈内存对于处理嵌套函数调用和递归的内存使用很有帮助。重复次数过多的递归可能会占用过多的栈内存。当这种情况发生时,称为**栈溢出**。



×

联系销售

如果您想将 W3Schools 服务用于教育机构、团队或企业,请发送电子邮件给我们
sales@w3schools.com

报告错误

如果您想报告错误,或想提出建议,请发送电子邮件给我们
help@w3schools.com

W3Schools 经过优化,旨在方便学习和培训。示例可能经过简化,以提高阅读和学习体验。教程、参考资料和示例会不断审查,以避免错误,但我们无法保证所有内容的完全正确性。使用 W3Schools 即表示您已阅读并接受我们的使用条款Cookie 和隐私政策

版权所有 1999-2024 Refsnes Data。保留所有权利。W3Schools 由 W3.CSS 提供支持