C学习_动态内存-1.12

学习内容:

动态内存开辟

按需分配,属于内存堆区范畴,由使用者手动开辟和释放空间。

1.malloc()

void* malloc(size_t size);
1)用于开辟size个字节的空间。
2)数据类型根据你所要使用的数据类型将void*强制类型转换。例如,你已知你要是用的是int型,则(int*)malloc()。void*不可作解引用操作(现在想想,void没有类型约束,少一个约束,则不确定)
3)固定使用四个语句,反正记住一起用
void* p=malloc(size_t size);//先存一下开辟空间起始地址
if (p==NULL)//判断是否成功开辟了空间,内存里是否有足够的空间。
{
perror(“main”);//没有就报错
return 0;
}
free(p);//使用完,记得释放空间。不释放,内存泄露。
p=NULL;//free函数只是释放空间,p的地址依旧在,但是如果之后错误访问就是越界的非法访问了,要记得回0。

疑惑:这么厉害的程序员,写free库函数就不能帮着归NULL?
解答:归NULL,你是不是要传&p过去,费劲地写了free(p,&p),不如一句话p=NULL。而且这仅仅涉及是不安全的,不算严重的事。

2.calloc()

开辟数组空间,初始化全为0。
void* calloc(size_t num, size_t size);
void* calloc(10,sizeof(int));//开辟10个大小为4个字节int型的数组,其元素全为0。

3.realloc()

调整已经开辟的内存大小。
void* calloc(void* memblock, size_t size);
realloc(p,100*sizeof(int));//调整之前开辟的p变量为100个整形空间。
逻辑流程:
1)尽量连续,后面空间够,接着写。
2)不够,另找一块空间,拷贝原内容进去。再继续调整大小。
3)这些开辟空间的都需要考虑内存不够的情况,是否返回的是NULL。

动态内存常见错误

1)内存够不够?是不是返回的NULL?
2)我释放了空间,忘记p=NULL,下次用p是越界访问。
3)free是在堆区范畴,只能用于动态内存函数,且一次性释放整体空间。(这里就涉及到一个问题,你的空间起始地址必须保留,就如同上次我们看的编译器给函数划分内存空间一样,先把栈底的值保留下来,当函数调用完后,根据栈底值返回)
4)忘记free了,内存泄露,一查每块地址都名花有主了。(能使用的内存越来越少)

小题

1.传值||传值看的是传的参数本身

如:
get(address)--------->void get(char* p);
这是传值还是传址?刚开始看传的是地址,以为是传址了。但是这要看参数本身,这里传的是address的值而不是&address的地址,所有是传值。

2.栈空间的销毁是连内容一并销毁

如:
调用函数中: char arr[]=“hello”; return arr;
返回了arr数组首元素地址,(刚开始以为销毁就销毁,相当于回收了内存,其实不是)并且调用函数结束后,arr地址后的内容也被销毁了。所有栈空间不能这样返回地址。
区别
调用函数中: char* arr=“hello”; return arr;
这里存的是“h”的常量地址,存在只读数据段,为全局变量,是字符常量,所以地址可以被正确返回。同理,静态变量也可以。它们不在临时存放的栈区。

3.*的语法

int * a,b;//a是指针,b是int,一个*对应一个。

你可能感兴趣的:(c语言,学习)