【C语言】-- 动态内存

动态内存

1.动态内存分配

要点:

  1. 动态内存分配是在堆上开辟空间;
  2. 动态内存分配可以灵活地使用内存空间。

2.动态内存分配函数

2.1 malloc / calloc / realloc / free 总结
// Allocates memory blocks.

void* malloc (size_t size);// szie为要开辟空间的总大小

void* calloc (size_t num, size_t size);// num为元素类型的个数(Number of elements); size为该元素类型的大小

void* realloc (void* ptr, size_t size);// ptr为要重新开辟空间的其实地址; size为要重新开辟的大小

// Deallocates or frees a memory block.

void free (void* ptr);// ptr为所要释放空间的其实地址

知识要点:

  1. malloc / calloc / realloc / free这些动态内存分配函数和释放动态内存空间函数都声明在stdlib.h中;

    #include <stdlib.h> // 引入头文件
    
  2. malloc / calloc / realloc内存分配函数,是在堆上开辟一块连续可用的空间;

    image-20220929145341135

  3. malloc / calloc / realloc开辟成功则返回起始地址,开辟失败则返回NULL,所以要进行空指针判断,否则会发生空指针异常!;

  4. 函数的返回值为void*类型,这样可以让使用者根据自己的需求使用(强制类型转换);

  5. malloc和realloc函数在开辟空间时,不会初始化空间,而calloc函数会将空间初始化为0

    初始化

  6. realloc函数相当于内存扩容,而且在开辟好空间后会将原来的数据拷贝过来

    注意一个问题,realloc的第一个参数是一个指针,这个指针可以是任何指针吗
    展示,上例子:

    error

    ​————realloc()函数需两个参数:一个是包含地址的指针(该地址由之前的malloc()、calloc()或realloc()函数返回),realloc()函数的第一个参数若为空指针,相当于分配第二个参数指定的新内存空间,此时等价于malloc()、calloc()或realloc()函数。另一个是要新分配的内存字节数。

    翻译翻译:第一个参数,这个指针要么是空指针要么是开辟在堆上的指针

    realloc

  7. free函数,注意它是释放 动态分配 的内存空间!,且它和动态内存分配函数时成对存在的。

    7.1 释放动态空间

    7.2 与动态内存分配函数成对出现,否则可能会发生内存泄漏

    free

2.2 一些试题,实践实践!

例1:

void funMem(char* p)
{
	p = (char*)malloc(40);
}

void Test()
{
	char* str = NULL;
	funMem(str);
	strcpy(str, "hello world");
	printf("%s",str);
}

题解:

  • 首先将指针变量str作为参数,用指针变量p来接收,这相当于在栈上开辟一块空间(p)来保存str的值(地址),也即str和p的指向是相同的(NULL),或者说是地址的临时拷贝。
  • 虽然在函数funMem中将p的指向改为动态开辟的空间,但是str还是NULL; 而且p所指向的空间不知道是否开辟成功
  • 所以在字符串拷贝时会报错,向空指针拷贝,这不符合strcpy的使用规范

例一

请修改代码使其正常

void funMem(char** p)
{
	*p = (char*)malloc(40);
}

void Test()
{
	char* str = NULL;
	funMem(&str);
	strcpy(str, "hello world");
	printf("%s",str);
}

1改

例2:

char* funM()
{
	char p[] = "hello world";
	return p;
}
void Test()
{
	char* str = NULL;
	str = funM();
	printf("%s", str);
}

题解:

  • 关键点在于funM函数中,将数组名p返回,也即返回数组的地址,但是数组是开辟在栈上的,属于临时变量,也就是函数就是栈帧销毁,则地址p为野指针!。
  • 那么str也是野指针,那么打印的内容则为随机值

例二

请修改代码使其正常

char* funM()
{
	static char p[] = "hello world"; // 用static关键字修饰是的数组的生命周期延长!
	return p;
}
void Test()
{
	char* str = NULL;
	str = funM();
	printf("%s", str);
}

2
over!this is jimmy.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值