Menu
×
   ❮   
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 测量地址处数据的 size。如果你忘记了 * 并改为写入 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 字节
自己试一试 »

备注

在使用动态内存分配时,你还应该**检查错误**并在程序结束时**释放内存**。你将在下一章中学习更多关于此方面的知识。


堆栈内存

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

当调用一个函数时,将为函数中的变量分配堆栈内存。当函数返回时,将释放堆栈内存。

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



×

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail:
[email protected]

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail:
[email protected]

W3Schools is optimized for learning and training. Examples might be simplified to improve reading and learning. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. While using W3Schools, you agree to have read and accepted our terms of use, cookie and privacy policy.

Copyright 1999-2024 by Refsnes Data. All Rights Reserved. W3Schools is Powered by W3.CSS.