网站源码下载音乐,北京网站制作公司清远,网站群建设公司排行榜,谷歌网站推广#x1f436;博主主页#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️#x1f525;专栏系列#xff1a;线性代数#xff0c;C初学者入门训练#xff0c;题解C#xff0c;C的使用文章#xff0c;「初学」C #x1f525;座右铭#xff1a;“不要等到什么都没有了#xff0c;才下… 博主主页ᰔᩚ. 一怀明月ꦿ ❤️专栏系列线性代数C初学者入门训练题解CC的使用文章「初学」C 座右铭“不要等到什么都没有了才下定决心去做” 大家觉不错的话就恳求大家点点关注点点小爱心指点指点 目录 动态内存管理
malloc
calloc
realloc
free
动态开辟常见的错误 动态内存管理 其实我们创建数组的时候系统为我们就是开辟了一段连续的空间这个空间一般是在栈区开辟的现在我们可以自己开辟一段空间。与动态开辟相关的函数malloc free calloc realloc 注意数组离开作用域时系统会自动释放这段空间如果我们自己动态开辟的空间离开作用域时系统是不会帮我们释放这段空间的如果要求释放这段动态开辟的空间我们就需要使用free函数去释放。 malloc malloc用于动态开辟内存引用的头文件是#includestdlib.h malloc的原型 void* malloc (size_t size); size_t size开辟的字节数 注意返回的类型是void*类型如果想要使用这段空间就必须强制性转化为自己想使用的类型例如int* p(int*)malloc(20);这就是开辟了20个字节然后把20个字节空间的首地址赋值给了p。 malloc的使用 malloc开辟成功会返回开辟好的空间的首地址 malloc如果申请内存失败会返回空指针NULL所以我们开辟好空间的话需要去判断一下 #includestdio.h
#includestdlib.h
#includeerrno.h
#includestring.h
int main()
{int *p(int *)malloc(20);//开辟了20个字节的空间if(pNULL){printf(%s\n,strerror(errno));//打印开辟失败的原因}free(p);pNULL;return 0;
} malloc开辟空间不初始化里面存放的随机值 #includestdio.h
#includestdlib.h
int main()
{int *p(int *)malloc(20);//开辟了20个字节的空间for(int i0;i5;i){printf(%d ,*(pi));}//使用for(int i0;i5;i){*(pi)i1;}for(int i0;i5;i){printf(%d ,*(pi));}free(p);pNULL;return 0;
} calloc calloc用于动态开辟内存区别于malloc的是calloc会初始化开辟的空间将开辟的空间全部初始化为0引用的头文件是#includestdlib.h calloc的原型 void* calloc (size_t num, size_t size); size_t num开辟的个数 size_t size开辟的类型的大小 注意返回的类型是void*类型如果想要使用这段空间就必须强制性转化为自己想使用的类型例如int* p(int*)calloc(20,sizeof(int));这就是开辟了20个整形的空间然后把20个整形空间的首地址赋值给了p。 calloc的使用 calloc开辟空间初始化里面存放的0 #includestdio.h
#includestdlib.h
int main()
{int *p(int *)calloc(20,sizeof(int));//开辟了20个int类型的空间for(int i0;i20;i){printf(%d ,*(pi));}free(p);pNULL;return 0;
} realloc realloc用于原空间不足继续开辟更大的空间引用头文件为#includestdlib.h realloc的原型 void* realloc (void* ptr, size_t size); void* ptr原空间的首地址 size_t size开辟新空间的大小 注意realloc开辟空间会遇到两种情况 1.如果原空间后面空间充足 在原空间后面继续开辟空间(返回的地址与原来的地址相同) 2.如果原空间后面空间不足 1realloc会找更大的空间 2将原来的数据拷贝到新空间 3释放原来的旧的空间 4返回新空间的地址(返回的地址与原来的地址不同) realloc的使用 #includestdio.h
#includestdlib.h
#includestring.h
#includeerrno.h
int main()
{int *p(int *)malloc(20);//开辟了20个int类型的空间if(pNULL){printf(%s\n,strerror(errno));}for(int i0;i5;i){printf(%d ,*(pi));}int* pc(int*)realloc(p,sizeof(p)*2);//在原空间进行扩展if(pc!NULL){ppc;//把空间首地址还是赋给pfor(int i0;i10;i){printf(%d ,*(pi));}}else{printf(realloc%s\n,strerror(errno));//如果开辟失败打印原因}free(p);pNULL;return 0;
} free free用于释放动态开辟的空间引用头文件#includestdlib.h free的原型 void free (void* ptr); void* ptr动态开辟空间的首地址 注意释放的空间一定是动态开辟的就是在堆上开辟的不然free是不起作用的。 free的使用 #includestdio.h
#includestdlib.h
int main()
{int* p(int *)malloc(20);//开辟了20个字节的空间free(p);//将20个字节的空间还给了系统pNULL;//如果不把p置为空指针那么p就是野指针return 0;
} 动态开辟常见的错误 可能开辟空间失败然后再去解引用会发生错误所以malloc的返回值要去判断和越界访问。 #includestdio.h
#includestdlib.h
#includestring.h
#includeerrno.h
int main()
{int* p(int*)malloc(20);//可能开辟空间失败然后再去解引用会发生错误所以malloc的返回值要去判断//所以我们需要判断if(pNULL){printf(%s,strerror(errno));//打印发生的错误return; }for(int i0;i5;i){p[i]i;}//越界访问for(int i0;i10;i)//只开辟了5个int类型的空间却访问了10个int类型的空间{p[i]i;}free(p);pNULL;return 0;
} 对非动态开辟的空间进行释放 #includestdio.h
#includestdlib.h
int main()
{int arr[10]{1,2,3};int *parr;free(p);//对非动态开辟的空间进行释放return 0;
} 释放一部分动态开辟的空间 #includestdio.h
#includestdlib.h
int main()
{int* p(int*)malloc(40);for(int i0;i10;i){p[i]i;}p;//p指向的就不是动态开辟空间的首地址free(p);//使用free释放一块动态开辟内存的一部分,不是从开辟空间的首地址开始释放的pNULL;return 0;
} 对一块空间多次释放 #includestdio.h
#includestdlib.h
int main()
{int* p(int*)malloc(40);free(p);//pNULL;//如果释放了指针之后再次释放是不会出错的因为指针为空时free不会做出任何反应free(p);//重复释放pNULL;return 0;
} 不能对空指针进行解引用操作 #includestdio.h
#includestring.h
#includestdlib.h
void GetMemory(char* str)
{str(char *)malloc(20);//str是p的临时拷贝malloc动态开辟的空间将首地址给了strp仍然是空指针
}
int main()
{char* pNULL;GetMemory(p);strcpy(p,hello world);//这里对空指针进行了解引用操作printf(%s,p);return 0;
}野指针问题 #includestdio.h
#includestring.h
#includestdlib.h
char* GetMemory(void)
{char str[]hello world;//返回栈区空间的问题//GetMemory函数内部创建的数组strstr是临时创建虽然返回了str数组的首地址但是离开GetMemory函数之后str内存会归还给系统p的值虽然还是str数组的首地址但是str空间已经归还给系统str再去访问就是非法访问了。栈区开辟的空间离开作用域栈区开辟的空间会被销毁return str;
}
int main()
{char* pNULL;pGetMemory();printf(%s,p);return 0;
} 注一定要记住 栈区局部变量函数形参 堆区动态管理的空间(malloc,realloc,calloc,free) 静态区静态变量全局变量 如果大家还有不懂或者建议都可以发在评论区我们共同探讨共同学习共同进步。谢谢大家