动态内分配——C语言

目录

内存分布图

 动态内存分配

malloc

free

calloc

realloc(调整动态内存开辟的大小)

动态分配的注意事项


内存分布图

 动态内存分配

malloc

描述

C 库函数 void *malloc(size_t size) 分配所需的内存空间,并返回一个指向它的指针。

声明

void *malloc(size_t size)

参数

  • size -- 内存块的大小,以字节为单位。

返回值

该函数返回一个指针 ,指向已分配大小的内存。如果请求失败,则返回 NULL。

使用

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
	//像内存申请10个整形的空间
	int* p = (int*)malloc(10 * sizeof(int));
	int i = 0;
	//判断是否开辟成功
	if (p == NULL)
	{
		printf("%s\n", strerror(errno));
	}
	else
	{
		for (i = 0; i < 10; i++)
		{
			*(p + i) = i;
		}
		for (i = 0; i < 10; i++)
		{
			printf("%d", *(p + i));
		}
		
	}
	return 0;
}

free

描述

C 库函数 void free(void *ptr) 释放之前调用 calloc、malloc 或 realloc 所分配的内存空间。

声明

void free(void *ptr)

参数

  • ptr -- 指针指向一个要释放内存的内存块,该内存块之前是通过调用 malloc、calloc 或 realloc 进行分配内存的。如果传递的参数是一个空指针,则不会执行任何动作。

返回值

该函数不返回任何值。

注释

free释放ptr指向的空间后,并不会把str置为NULL,要自行将其置为空指针。

使用

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
	//像内存申请10个整形的空间
	int* p = (int*)malloc(10 * sizeof(int));
	int i = 0;
	//判断是否开辟成功
	if (p == NULL)
	{
		printf("%s\n", strerror(errno));
	}
	else
	{
		for (i = 0; i < 10; i++)
		{
			*(p + i) = i;
		}
		for (i = 0; i < 10; i++)
		{
			printf("%d", *(p + i));
		}
		//当动态申请的空间不再使用的时候
		//就应该还给操作系统
		free(p);
		p = NULL;
	}
	return 0;
}

calloc

描述

C 库函数 void *calloc(size_t nitems, size_t size) 分配所需的内存空间,并返回一个指向它的指针。malloc 和 calloc 之间的不同点是,malloc 不会设置内存为零,而 calloc 会设置分配的内存为零。

声明

void *calloc(size_t nitems, size_t size)

参数

  • nitems -- 要被分配的元素个数。
  • size -- 元素的大小。

返回值

该函数返回一个指针,指向已分配的内存。如果请求失败,则返回 NULL。

使用

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
	//像内存申请10个整形的空间
	int* p = (int*)calloc(10, sizeof(int));
	int i = 0;
	//判断是否开辟成功
	if (p == NULL)
	{
		printf("%s\n", strerror(errno));
	}
	else
	{
		for (i = 0; i < 10; i++)
		{
			*(p + i) = i;
		}
		for (i = 0; i < 10; i++)
		{
			printf("%d", *(p + i));
		}
		//当动态申请的空间不再使用的时候
		//就应该还给操作系统
		free(p);
		p = NULL;
	}
	return 0;
}

注释:会将元素初始化为零 

realloc(调整动态内存开辟的大小)

让动态内存的开辟变得更加灵活

描述

C 库函数 void *realloc(void *ptr, size_t size) 尝试重新调整之前调用 malloc 或 calloc 所分配的 ptr 所指向的内存块的大小.

声明

void *realloc(void *ptr, size_t size)

参数

  • ptr -- 指针指向一个要重新分配内存的内存块,该内存块之前是通过调用 malloc、calloc 或 realloc 进行分配内存的。如果为空指针,则会分配一个新的内存块,且函数返回一个指向它的指针。
  • size -- 内存块的新的大小,以字节为单位。如果大小为 0,且 ptr 指向一个已存在的内存块,则 ptr 所指向的内存块会被释放,并返回一个空指针。

返回值

该函数返回一个指针 ,指向重新分配大小的内存。如果请求失败,则返回 NULL。

用法:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
	//像内存申请5个整形的空间
	int* p = (int*)malloc(5*sizeof(int));
	int i = 0;
	//判断是否开辟成功
	if (p == NULL)
	{
		printf("%s\n", strerror(errno));
	}
	else
	{
		for (i = 0; i < 5; i++)
		{
			*(p + i) = i;
		}
//在使用malloc开辟的20个字节空间
// 		   假设这里二十个字节不能满足我们的使用
// 		   希望我们能够有四十字节个空间
// 
		int* ptr = realloc(p, 40);
		if (ptr != NULL)
		{
			p = ptr;
		}
		for (i = 5; i < 10; i++)
		{
			*(p + i) = i;
		}
		//当动态申请的空间不再使用的时候
		//就应该还给操作系统
		free(p);
		p = NULL;
	}

	return 0;
}

注意:

1.原有的空间之后有足够大的空间,会在原本的空间后进行拓展开辟。

2.原有的空间之后没有足够大的空间,会重新开辟一段空间,将之前内容进行复制,然后将原有的空间进行释放。

3.malloc函数的返回的是无类型指针,在使用时一定要强制转换为所需要的类型。
4.重点:在使用malloc开辟空间时,使用完成一定要释放空间,如果不释放会造内存泄漏。
5.在使用malloc函数开辟的空间中,不要进行指针的移动,因为一旦移动之后可能出现申请的空间和释放空间大小的不匹配(eg:p++)
 

动态分配的注意事项

1.对NULL解引用操作

(在开辟空间时,可能开辟不成功就会返回空指针,因此在开辟后对其进行判断)

2.对动态开辟内存的越界访问。

3.对非动态开辟的内存使用free释放

4.使用free释放动态开辟内存的一部分。

(指针位置不能发生移动)

5.对同一块动态内存的多次释放

6.动态开辟内存忘记释放(内存泄漏)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

binary~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值