添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
细心的佛珠  ·  vscode ...·  1 年前    · 
行走的石榴  ·  clr - Why does not C# ...·  1 年前    · 

首先从思维导图大概了解一下malloc,realloc和calloc函数

malloc,calloc,realloc函数详解_i++

1.malloc函数

malloc,calloc,realloc函数详解_#include_02

函数功能:malloc能从堆区申请空间给与我们使用,同时返回那片空间所处的首位置的地址。从图我们也能看到malloc返回的为void*类型的指针。

我们从下面的代码来了解这个函数


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
int main()
	//申请空间
	int* a = (int*)malloc(20);//这个代码malloc函数会从堆区上申请20个字节的空间,并将这个空间的首地址返回,
	//但是这个返回去的地址是void*类型的所以要进行强制类型转换
	//使用空间
	if (a == NULL)
		printf("error:%s", strerror(errno));
    return 0;//当空间创建失败的时候也就不用再继续执行代码了所以提前返回
	for (int i = 0; i < 5; i++)
		a[i] = i + 1;
	for (int i = 0; i < 5; i++)
		printf("%d", a[i]);
	//释放空间(当我们使用空间完毕后要将其释放)
	//使用free
	free(a);//这个代码的意思就是将从a开始的在堆区上的空间返回给系统,
	//但是此时的a里的地址指向任然是那片空间,此时的a就成了野指针
	a = NULL;//将a里的值修改成空
	return 0;
}

代码运行结果:

malloc,calloc,realloc函数详解_c函数_03

当我将上面的malloc创建的空间改为2000000000000000000运行结果就会

malloc,calloc,realloc函数详解_#include_04

如果不进行判断那么就可能出现问题,所以判断空间是否开辟成功是不可或缺。

总结: 使用malloc函数创建空间的时候要注意返回值要强制类型转换,否则无法使用还有每一个内存

创建函数创建空间后,使用完空间后要释放空间,同时将指向那片空间的指针赋值为空指针。

2.calloc

函数功能:和malloc函数一样但是会将创建的空间里面的值全部初始化为0

malloc,calloc,realloc函数详解_c函数_05

这是上面的那个代码运行后a,以及里面所储存的值地址可以看到地址指向的空间里面所储存的值为-842150451,这就是编译器在创建空间时默认给的值,可见malloc函数并不会将所创建的空间里面的值给初始化,但是calloc就会

malloc,calloc,realloc函数详解_#include_06

同样是创建20个字节大小的空间:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
int main()
	//申请空间
	int* a = (int*)calloc(5,sizeof(int));//这个代码calloc函数会从堆区上申请20个字节的空间,并将这个空间的首地址返回,
	//前面的5就代表申请的空间为5个元素大小,后面的表达式代表一个元素的大小。
	//但是这个返回去的地址是void*类型的所以要进行强制类型转换
	//使用空间
	if (a == NULL)
		printf("error:%s", strerror(errno));
		return 0;
	for (int i = 0; i < 5; i++)
		a[i] = i + 1;
	for (int i = 0; i < 5; i++)
		printf("%d", a[i]);
	//释放空间(当我们使用空间完毕后要将其释放)
	//使用free
	free(a);//这个代码的意思就是将从a开始的在堆区上的空间返回给系统,
	//但是此时的a里的地址指向任然是那片空间,此时的a就成了野指针
	a = NULL;//将a里的值修改成空
	return 0;
}

cealloc运行可见cealloc创建的空间会被初始化为0

malloc,calloc,realloc函数详解_#include_07

3.realloc

malloc,calloc,realloc函数详解_#include_08

函数功能:修改ptr指向的空间大小,修改为size字节的大小。

代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
int main()
	//申请空间
	int* a = (int*)malloc(20);//这个代码calloc函数会从堆区上申请20个字节的空间,并将这个空间的首地址返回,
	//前面的5就代表申请的空间为5个元素大小,后面的表达式代表一个元素的大小。
	//但是这个返回去的地址是void*类型的所以要进行强制类型转换
	//使用空间
	if (a == NULL)
		printf("error:%s", strerror(errno));
		return 0;
	for (int i = 0; i < 5; i++)
		a[i] = i + 1;
	int* pc=(int*)realloc(a, 40);//这个代码的功能就是修改a所指向的那片空间的大小,并且返回首空间的地址
	if (pc == NULL)
		printf("error:%s", strerror(errno));
		return 0;
	a = pc;
	for (int i = 5; i < 10; i++)
		a[i] = i + 1;
	for (int i = 0; i < 10; i++)
		printf("%d ", a[i]);
	//释放空间(当我们使用空间完毕后要将其释放)
	//使用free
	free(a);//这个代码的意思就是将从a开始的在堆区上的空间返回给系统,
	//但是此时的a里的地址指向任然是那片空间,此时的a就成了野指针
	a = NULL;//将a里的值修改成空
	return 0;
}

运行结果:

malloc,calloc,realloc函数详解_#include_09

接下来我们思考以下问题:

1.realloc创建的新空间是否被初始化过呢?

malloc,calloc,realloc函数详解_#include_10

从图我们能知道很明显并没有。

2.既然realloc会扩大空间那么如果扩大后的空间会占用其它函数创建的空间,那么此时realloc函数又会返回那里的地址呢?

验证代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
int main()
	//申请空间
	int* a = (int*)malloc(20);//这个代码calloc函数会从堆区上申请20个字节的空间,并将这个空间的首地址返回,
	//前面的5就代表申请的空间为5个元素大小,后面的表达式代表一个元素的大小。
	//但是这个返回去的地址是void*类型的所以要进行强制类型转换
	//使用空间
	if (a == NULL)
		printf("error:%s", strerror(errno));
		return 0;
	for (int i = 0; i < 5; i++)
		a[i] = i + 1;
	int* pc=(int*)realloc(a, 4000000000);//这个代码的功能就是修改a所指向的那片空间的大小,并且返回首空间的地址
	if (pc == NULL)
		printf("error:%s", strerror(errno));
		return 0;
	a = pc;
	for (int i = 5; i < 10; i++)
		a[i] = i + 1;
	for (int i = 0; i < 10; i++)
		printf("%d ", a[i]);
	//释放空间(当我们使用空间完毕后要将其释放)
	//使用free
	free(a);//这个代码的意思就是将从a开始的在堆区上的空间返回给系统,
	//但是此时的a里的地址指向任然是那片空间,此时的a就成了野指针
	a = NULL;//将a里的值修改成空
	return 0;
}

下面的图片是我调式得来的,此时运行到了刚刚扩大新空间

从这我们就能知道realloc确实扩大了空间不过不是从原空间开始扩展的,而是换了一个有这么多大小并且不会占用其它函数空间的空间,并且返回了那个新空间的首地址

malloc,calloc,realloc函数详解_i++_11

但是如果我们执行下面的代码又会发现不同情况

验证代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
int main()
	//申请空间
	int* a = (int*)malloc(20);//这个代码calloc函数会从堆区上申请20个字节的空间,并将这个空间的首地址返回,
	//前面的5就代表申请的空间为5个元素大小,后面的表达式代表一个元素的大小。
	//但是这个返回去的地址是void*类型的所以要进行强制类型转换
	//使用空间
	if (a == NULL)
		printf("error:%s", strerror(errno));
		return 0;
	for (int i = 0; i < 5; i++)
		a[i] = i + 1;
	int* pc=(int*)realloc(a, 40);//这个代码的功能就是修改a所指向的那片空间的大小,并且返回首空间的地址
	if (pc == NULL)
		printf("error:%s", strerror(errno));
		return 0;
	a = pc;
	for (int i = 5; i < 10; i++)
		a[i] = i + 1;
	for (int i = 0; i < 10; i++)
		printf("%d ", a[i]);
	//释放空间(当我们使用空间完毕后要将其释放)
	//使用free
	free(a);//这个代码的意思就是将从a开始的在堆区上的空间返回给系统,
	//但是此时的a里的地址指向任然是那片空间,此时的a就成了野指针
	a = NULL;//将a里的值修改成空
	return 0;
}

可见此时realloc返回的值还是原来空间的地址,因为此时这片空间可以扩大到我们要求的大小,并且不会占据其它函数空间,所以返回了原来的地址。

malloc,calloc,realloc函数详解_i++_12

由此我们也就能知道:

realloc函数当原空间能扩大到我们所要求的大小并且不会占据其它函数的空间,那么它就会返回原来空间的地址,但是当原空间不能扩大到我们所要求的大小或是会占据其它函数的空间之时,reallco就会释放原空间并去找到一个新空间能满足我们的要求并且不会占据其它函数空间,之后返回这片新空间的首地址。

这篇文章就写到这里了,希望能对阅读的你有所帮助,如果发现任何错误,请严厉指出,我一定虚心接收并且改正。

Pytorch保留验证集上最好的模型 pytorch保存训练好的模型

PyTorch学习系列(十四)——保存训练好的模型PyTorch提供了两种保存训练好的模型的方法。 第一种是只保存模型参数,这也是推荐的方法:#保存 torch.save(the_model.state_dict(), PATH) the_model = TheModelClass(*args, **kwargs) the_model.load_state_dict(torch.

python 抢优惠券 python优惠券机器人

介绍这个例子主要利用turtle库实现根据输入动态展示不同机器人的图像和属性信息。代码部分非原创只是做了些许修改和整理使得更易阅读。图片和文件资源请访问git仓库获取:链接地址涉及以下知识点:1.文件读取2.字典3.turtle库的使用4.控制语句实现的效果代码#!/bin/python3 from turtle import * from random import choice screen

java 统计文件夹大小写 java统计大小写字母个数

单个字符相比较,实际上比较的是ASCII值chs[i] >= 'A' && chs[i] <= 'Z' 大写字母范围chs[i] >= 'a' && chs[i] <= 'z' 小写字母范围package doudou; public class test_Count_String { public static