动态内存分配与指向它的指针变量

这篇博客介绍了C语言中的内存动态分配概念,包括如何使用malloc函数在堆区开辟空间,以及通过指针操作动态内存。同时展示了如何通过sizeof运算符获取数据类型的字节数,并提供了示例代码演示了动态分配内存存储多个整数及其释放的过程。

什么是内存的动态分配?
全局变量是分配在内存中的静态存储区的,非静态的局部变量(包括形参)是分配在内存中的动态存储区的,这个存储区是一个称为栈(stack)的区域。

C语言还允许建立内存动态分配区域,以存放一些临时用的数据,需要时随时开辟,不需要时随时释放。这些数据是临时存放在一个特别的自由存储区,称为堆(heap)区。只能通过指针来引用。
在这里插入图片描述
int *pt;
pt=(int *)malloc(100); //malloc(100)是void *型,把它转换为int *型

注意:不要把“指向void类型”理解为能指向“任何的类型”的数据,而应理解为“指向空类型”或“不指向确定的类型”的数据。<\font>

sizeof:
是一个运算符,给出某个类型或变量在内存中所占据的字节数

#include <stdio.h>
int main()
{
	int a;
	a=6;
	printf("sizeof=%d",sizeof(double));
	printf("\nsizeof=%d",sizeof(a));
}
#include <stdio.h>
#include <stdlib.h>    //程序中用了molloc函数,应包含stdib.h 
int main()
{
	void check(int *);//函数声明 
	int *p1,i;        //p1是int型指针,只保存地址和类型 
	p1=(int *)malloc(5*sizeof(int));//开辟动态内存区,将地址转换成int*型,然后放在p1中
	//p1得到了int*型地址 
	for(i=0;i<5;i++)
		scanf("%d",p1+i);//输入5个学生的成绩 
	check(p1);
	return 0;
	
		
}
void check(int *p)       //定义check函数,形参是int*指针 
{
	int i;
	printf("They are fail:");
	for(i=0;i<5;i++)
		if(p[i]<60) printf("%d ",p[i]);//输出不合格的成绩 
	printf("\n");
}
 
### 动态内存分配中的释放对象 在动态内存分配中,`free()` 函数的作用是释放由 `malloc()` 或 `calloc()` 分配动态内存空间[^1]。需要注意的是,`free()` 并不会释放指针变量本身,而是释放指针变量指向动态内存区域。 当调用 `free(p)` 时,其中 `p` 是一个指针变量,它应该保存着之前通过 `malloc()` 或 `calloc()` 返回的地址。执行 `free(p)` 后,原本由 `p` 指向的那块动态分配的空间会被标记为可重用状态,但这并不会影响指针变量 `p` 的存在否或者其存储的内容。换句话说,`p` 仍然会保留原来的值(即原来指向的那个地址),尽管那个地址对应的内存已经被释放了[^1]。 为了避免后续程序错误地再次访问已被释放的内存,通常建议在调用 `free(p)` 后立即将指针设置为空 (`NULL`): ```c free(p); p = NULL; ``` 这样做的好处在于如果之后不小心又尝试去解引用这个已经失效的指针,则容易引发运行期异常或崩溃,从而帮助开发者更快发现问题所在。 另外,在 C++ 中虽然也有类似的机制来管理堆上的对象生命周期,但是更推荐使用智能指针等现代特性来自动生成这些资源管理工作,减少手动干预带来的风险[^2]。 综上所述,在讨论动态内存分配的时候,“释放”的概念针对的是实际申请到的那一片连续的存储单元而非单纯意义上的某个特定指针实体;而所谓“指针”,更多时候只是作为记录这块数据位置的一个工具而已。 #### 示例代码展示如何正确处理动态内存 下面给出一段简单的例子演示上述原则的应用场景: ```c #include <stdio.h> #include <stdlib.h> int main() { int *ptr = (int *)malloc(sizeof(int)); // 分配单个整数大小的内存 if(ptr != NULL){ *ptr = 42; // 给新分配内存赋初值 printf("Value stored at ptr:%d\n",*ptr); free(ptr); // 释放刚才分配出来的内存 ptr=NULL; // 将原指针置零 //*ptr=99; // 此处若未先设成null则可能触发非法操作警告/错误 // (具体取决于编译器实现) printf("After freeing, trying to dereference gives:"); if(ptr==NULL) puts("safe guard hit!"); else printf("%d\n",*ptr); } return EXIT_SUCCESS; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值