大佬教程收集整理的这篇文章主要介绍了C 动态内存分配,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我们已经掌握的内存开辟方式有:@H_197_3@
int val=20;//在栈空间上开辟四个字节 char arr[10]={0};//在栈空间上开辟10个字节连续空间
但是上述的开辟空间方式有2个特点@H_197_3@
1.空间开辟大小固定@H_197_3@
2.数组在声明的时候,必须指定数组长度,它所需要的内存在编译时分配@H_197_3@
但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道,那数组的编译时开辟空间的方式就不能满足了。这时候就要尝试开辟动态内存@H_197_3@
·malloc@H_197_3@
这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。@H_197_3@
1.如果开辟成功,则返回一个指向开辟好空间的指针。@H_197_3@
2.如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。@H_197_3@
3.返回值的类型时void *,所以malloc函数并不知道开辟空间类型,具体在使用的时候使用者自己来决定。@H_197_3@
4.如果参数size为0,malloc的行为是标准是未定义的,取决于编辑器。@H_197_3@
举个列子@H_197_3@
//内存申请10个整形空间 int *p = (int *)@H_157_6@malloc(10 * sizeof(int)); if (p==NULL) { //打印错误 printf("%s", strerror(errno)); } else { for (size_t i = 0; i < 10; i++) { *(p + i) = i; printf("%d\r\n", *(p + i)); } }
·free @H_197_3@
void free(void * ptr);
free函数专门用来做动态内存释放和回收的@H_197_3@
1.参数ptr指向的空间不是动态开辟的,那free函数的行为是未定义的@H_197_3@
2.参数prt是NULL指针,则函数什么事都不做。@H_197_3@
举个例子@H_197_3@
//内存申请10个整形空间 int *p = (int *)@H_157_6@malloc(10 * sizeof(int)); if (p==NULL) { //打印错误 printf("%s", strerror(errno)); } else { for (size_t i = 0; i < 10; i++) { *(p + i) = i; printf("%d\r\n", *(p + i)); } } //当动态申请空间不在使用,应该还给操作系统 free(p);
但是实际上free(p)后的指针依然指向这些内存防止误操作和内存泄漏这些内存应该让p置空@H_197_3@
//内存申请10个整形空间 int *p = (int *)@H_157_6@malloc(10 * sizeof(int)); if (p==NULL) { //打印错误 printf("%s", strerror(errno)); } else { for (size_t i = 0; i < 10; i++) { *(p + i) = i; printf("%d\r\n", *(p + i)); } } //当动态申请空间不在使用,应该还给操作系统 free(p); p=NULL;//置空
·calloc@H_197_3@
void * calloc(size_t num,size_t sizE);
1.函数功能是为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0;@H_197_3@
2.与函数malloc的区别只在于calloc会在返回地址之前把申请的空间每个字节初始化为0@H_197_3@
例如@H_197_3@
int *p = (int *)calloc(10 , sizeof(int)); if (p==NULL) { //打印错误 printf("%s", strerror(errno)); } else { for (size_t i = 0; i < 10; i++) { //*(p + i) = i; printf("%d\r\n", *(p + i)); } }
·realloc@H_197_3@
void * realloc(void * ptr, size_t sizE);
1.realloc函数的出现让内存管理更加灵活@H_197_3@
2.有时候我们发现过去申请的空间太小了,有时候我们又觉得申请的空间过大了,为了合理的管理内存@H_197_3@
对他们做调整,realloc函数客园做到对动态开辟内存大小做调整@H_197_3@
3.ptr要调整的内存地址@H_197_3@
4.size调整之后新大小@H_197_3@
6.这个函数原内存空间大小基础上,还会将原来内存中的数据移动到新的空间(改变地址)@H_197_3@
7.realloc 在调整内存空间存在2种情况@H_197_3@
7.1 原有空间足够大 不需要重新开辟直接在原有基础减少就好了@H_197_3@
7.2 原有空间足够大 需要重新开辟把原先存在的值复制到新的地址中@H_197_3@
int *p = (int *)calloc(5 , sizeof(int)); if (p==NULL) { //打印错误 printf("%s", strerror(errno)); } else { for (size_t i = 0; i < 5; i++) { *(p + i) = i; } //申请40个空间 int *p2 = (int *)realloc(p, 40); for (size_t i = 5; i < 10; i++) { *(p + i) = i; } for (size_t i = 0; i < 10; i++) { printf("%d\r\n", *(p + i)); } } //当动态申请空间不在使用,应该还给操作系统 free(p);
当我们申请空间较小时运行可以看到@H_197_3@
@H_197_3@
@H_197_3@
2个地址相同 代码没什么@H_197_3@
可以看到返回新地址了 它在后面地址地址不够后 会选择重新开辟空间@H_197_3@
1.对NULL指针解引用操作@H_197_3@
void test() { int *p = (int *)@H_157_6@malloc(10 * sizeof(INT_MAX)); *p = 20;//如果p的值是NULL,就会有问题 free(p);
}
2.对动态开辟空间越界访问@H_197_3@
void test() { int *p = (int *)@H_157_6@malloc(10 * sizeof(int)); *p = 20;//如果p的值是NULL,就会有问题 if (p == NULL) { //打印错误 printf("%s", strerror(errno)); } for (size_t i = 0; i <=10; i++) { *(p + i) = i;//当等于10就会存在越界 } free(p); }
3.对非动态开辟内存使用free释放@H_197_3@
4.使用free释放一块动态开辟内存的一部分@H_197_3@
5.对同一块动态内存多次释放@H_197_3@
int *p = (int *)@H_157_6@malloc(10 * sizeof(int)); *p = 20;//如果p的值是NULL,就会有问题 if (p == NULL) { //打印错误 printf("%s", strerror(errno)); } free(p); p = NULL; free(p);
6.动态开辟内存忘记释放(内存泄漏)@H_197_3@
@H_197_3@
以上是大佬教程为你收集整理的C 动态内存分配全部内容,希望文章能够帮你解决C 动态内存分配所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。