跨境派

跨境派

跨境派,专注跨境行业新闻资讯、跨境电商知识分享!

当前位置:首页 > 卖家故事 > C语言之动态内存管理

C语言之动态内存管理

时间:2024-03-30 21:40:31 来源:网络cs 作者:峨乐 栏目:卖家故事 阅读:

标签: 管理  动态  语言 
阅读本书更多章节>>>>

       在C语言中我们在栈上开辟的空间是固定的,一旦确定好大小就不能随意改变,就想你创建了

int i = 10;
int arr[10] = {0};
int i 一旦确定下来就是四个字节,arr一旦确定好大小在重新运行时也是不能改变的。

为此C语言引入了动态内存空间开辟,这是给程序员自主开辟好空间,并且这个空间是在堆上开辟的。

动态内存函数

头文件是stdlib.h

malloc

malloc 可以向堆上申请 size 个字节的空间大小,如果开辟成功就会返回相应的指针,并且对于开辟的空间是不会进行初始化赋值,里面都是随机值!
如果开辟空间失败就会返回NULL!
如果开辟0个字节的空间,返回值取决于特定的库实现,可能为NULL也可能不是.
要注意了返回的指针类型是 void*,所以我们需要强制类型转换为我们需要的。

由于可能会返回NULL,一旦被解引用就是野指针的非法访问。
所以我们要对返回的指针做检查

下面我们来实践一下:

#include <stdio.h>#include <stdlib.h>int main(){int* p = (int*)malloc(sizeof(int) * 5);if (p == NULL){perror("malloc");return 1;}// 使用return 0;}

free

介绍完malloc 函数后,我们来介绍一下如何释放空间,由于堆的空间是有限的,如果一直开辟不去释放空间,那就会一直占用堆上的空间,导致运行时发生内存泄漏。所以我们需要学会释放空间!

free只能对malloc,calloc和realloc 这些动态内存开辟函数开辟的空间进行释放空间,如果释放的不是这些空间那这个行为就是未定义的行为(也就是错误的)
如果你传过去的指针为NULL的话,那这个函数不会做任何事情
free函数不会改变你传过去的指针的值,所以在释放空件后,可以将指针置为NULL,避免野指针的使用

#include <stdio.h>#include <stdlib.h>int main(){int* p = (int*)malloc(sizeof(int) * 5);if (p == NULL){perror("malloc");return 1;}// 使用free(p);p = NULL;return 0;}

calloc

这个函数也是申请 num 个 size 大小的字节空间,唯一和malloc不同的是,calloc会将空间全部初始化为0

realloc

这个函数就是扩大空间的,如果你觉得malloc或者calloc开辟的空间小了,就传入一个指针,输入你想要扩大的字节数,就可以了。

如果你传的是空指针,那realloc就会像malloc一样,为你开辟一块空间并返回新空间的地址。
如果开辟失败就会返回空指针

这里的开辟方式分两种:

第一种是就地扩容,返回原来的指针
第二种是异地扩容,将原先的空间的值全部拷贝到新空间,并释放就空间,最后返回新空间的地址

#include <stdio.h>#include <stdlib.h>int main(){int* p = (int*)calloc(5, sizeof(int));if (p == NULL){perror("calloc");return 1;}// 使用int* ptr = (int*)realloc(p, 50);if (ptr == NULL){perror("realloc");return 1;}p = ptr;//使用free(p);p = NULL;return 0;}

练习

题目1

void test(){int* p = (int*)malloc(INT_MAX / 4);*p = 20;free(p);}

如果p的值是NULL,就是对空指针解引用,发生错误

题目2

void test(){int i = 0;int* p = (int*)malloc(10 * sizeof(int));if (NULL == p){exit(EXIT_FAILURE);}for (i = 0; i <= 10; i++){*(p + i) = i;}free(p);}

当i是10的时候就会越界访问

题目3

void test(){int a = 10;int* p = &a;free(p);}

对非动态内存开辟的空间不能使用free

题目4

void test(){int* p = (int*)malloc(100);p++;free(p);}

由于p已经不是原先的起始位置,释放的空间不彻底,导致内存泄漏

题目5

void test(){int* p = (int*)malloc(100);free(p);free(p);}

对一块动态开辟的内存多次释放是错误的,在第一次释放的时候,空间以及还给操作系统了,free是无权访问操作系统的空间,所以在使用free后,我们可以将指针置空,避免多次释放。

题目6

void test(){int* p = (int*)malloc(100);if (NULL != p){*p = 20;}}int main(){test();while (1);}

这个就是忘记对开辟的内存进行释放,导致内存泄漏。

笔试题

题目1

void GetMemory(char* p){p = (char*)malloc(100);}void Test(void){char* str = NULL;GetMemory(str);strcpy(str, "hello world");printf(str);}

首先str还是NULL,因为形参的改变不会影响实参,如果要改变str需要传入str的地址,对NULL解引用程序发生崩溃,并且对于开辟的内存空间要记得释放

题目2

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

临时变量p一旦出了GetMemory 函数就被销毁了,str非法访问内存空间。

题目3

void GetMemory(char** p, int num){*p = (char*)malloc(num);}void Test(void){char* str = NULL;GetMemory(&str, 100);strcpy(str, "hello");printf(str);}

忘记释放内存,发生内存泄漏

题目4

void Test(void){char* str = (char*)malloc(100);strcpy(str, "hello");free(str);if (str != NULL){strcpy(str, "world");printf(str);}}

free已经释放了str所指向的内存空间,但是free不会将str置空,后面的代码段内存空间进行了非法访问!

柔性数组

       柔性数组就是数组的大小是未定义的,这种一般出现在结构体上,如果不知道结构体的大小的话,可以看我上上篇的文章《结构体详解》。

柔性数组的创建:

struct S{int i;char arr[];};

特点

柔性数组前面必须要有一个成员
使用sizeof去计算这个结构体的时候,是没有包含柔性数组的大小(因为他还没大小)
包含柔性数组成员的结构⽤malloc ()函数进行内存的动态分配,并且分配的内存应该⼤于结构的大小,以适应柔性数组的预期大小。

使用

当我们要使用结构体是,就需要对这个柔性数组开辟空间:

#include <stdio.h>#include <stdlib.h>struct S{int i;char arr[];};int main(){struct S* s1;s1 = (struct S*)malloc(sizeof(int) + 10 * sizeof(char));return 0;}

这样子我们就获得了10个字节的arr数组的空间了。

优点

我们在学习链表的时候会定义下面的结构体:

#include <stdio.h>#include <stdlib.h>struct S{int data;struct S* next;};int main(){struct S* p;p = (struct S*)malloc(sizeof(struct S));if (p == NULL){perror("malloc p");return 1;}p->next = (struct S*)malloc(sizeof(struct S));if (p->next == NULL){perror("malloc next");return 1;}//使用free(p->next);p->next = NULL;free(p);p = NULL;return 0;}

当我们使用这个结构体的时候需要对内存进行两次释放,如果使用柔性数组就可以一次释放。
柔性数组的使用能让内存空间更加连续,减少内存碎片化。

阅读本书更多章节>>>>

本文链接:https://www.kjpai.cn/gushi/2024-03-30/151200.html,文章来源:网络cs,作者:峨乐,版权归作者所有,如需转载请注明来源和作者,否则将追究法律责任!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。

上一篇:线性规划问题

下一篇:返回列表

文章评论