1.栈区 后进先出, 从高到底分配内存
int a = 2;
int b = 3;
printf("栈区: %p\n", &a);
printf("栈区: %p\n", &b);<span style="font-family: Menlo; background-color: rgb(255, 255, 255);"> </span>
2.堆区
堆区分配内存, 从低到高
堆区的内存由我们自己进行分配和释放
int *c = malloc(10);
printf("堆区: %p\n", c);<span style="font-family: Menlo; background-color: rgb(255, 255, 255);"> </span>
3.静态区
全局变量和被static修饰的静态变量
静态变量 再一次程序执行过程中, 只分配一次内存
static int d = 5;
printf("静态: %p\n", &d);
4.常量区
内存是只读的, 不可修改
char *ss ="李四";
char *e = "zhangsan";
printf("常量: %p\n", e);
5.代码区
程序执行的代码都保存在代码区
void testMemory()
{
printf("代码区");
}
printf("代码: %p\n", testMemory);
当程序执行完毕. 全释放掉 常量区和静态区的内存
二.内存分配的相关函数
1.malloc函数
将堆区内存分配4个字节给一个int型的指针
返回值 void * 代表任意指针
参数; 分配的内存大小
考虑到平台不同, 可以用sizeof(char)来确定1个字节
int *p= malloc(sizeof(char) * 4);
使用:
*p = 4;
在堆区分配8个字节
char *pp = malloc(sizeof(char) * 8) ;
malloc 对内存的分配不负责清空内容
对str进行的操作和之前的指针操作一致, 比如可以进行字符窜拷贝
strcpystr(pp, "xiansen");
printf("%s\n", pp);
在堆区分配int类型的数据
int *ppp = malloc(sizeof(int) * 5);
结构体一样
Student *stu = malloc(sizeof(Student) * 3);
对分配的内存释放
无返回值, 有一个参数, 填任意类型的指针
释放内存的时候, 只是对内存标记为可用, 并没有对内存进行清空
free(stu);
free(pp);
free(p);
free(ppp);
free(c);
练习:有一字符串,其中包含数字,提取其中的数字.要求动态分配内存保存
// 定义变量来保存数字的个数
int count = 0;
// 定义一个字符串
char array[] = "1asd34f6asd4f3as1d";
char *p = array;
// 循环条件
while (*p != '\0') {
if (*p <= '9' && *p >= '0') {
count++;
}
// 每次循环都让指针向下移位
p++;
}
// 分配空间
char * pp = malloc(sizeof(char) * count + 1);
// 指针归位
p = array;
// 循环遍历
while (*p != '\0') {
if (*p <= '9' && *p >= '0') {
*pp = *p;
pp++;
}
// 在末尾添加'\0'
if(*(p + 1) == '\0')
{
*pp = '\0';
}
// 每次循环都让指针向下移位
p++;
}
// 指针归位
pp = pp - count;
// 打印
printf("%s", pp);
free(pp);
练习2:输入3个学员的姓名,动态分配内存保存学员姓名,并在最后输出
// 存储输入的内容
char *name[3] = {0};
char temp[50] = {0};
for (int i = 0; i < 3; i++) {
scanf("%s", temp);
// 根据输入文字的长度计算分配的内存
name[i] = malloc(sizeof(char) * strlen(temp) + 1);
strcpy(name[i], temp);
}
// 输出
for (int i = 0; i < 3; i++) {
printf("%s\n", name[i]);
}
// 释放
for (int i = 0; i < 3; i++) {
free(name[i]);
}
3.其他的内存管理函数
calloc
跟malloc一样, 区别在于在分配内存的时候清空所有内容, 在效率上略低
参数1: 分配多少个内存,
参数2: 每一个内存有多大
char *str = calloc(2, sizeof(char));
realloc
重新分配内存大小
参数1: 给谁分配
参数2: 重新分配的大小
str = realloc(str, 100);
三.内存操作函数
1.初始化内存
参数1: 初始化谁
参数2: 初始化的值
参数3: 初始化多少个字节
str = memset(str, 65, 13);
printf("%s\n", str);
2.内存拷贝函数
参数1: 拷贝到谁
参数2: 从谁拷贝(source)
参数3: 拷贝多少字节
跟字符串拷贝函数的区别; 字符串拷贝只能够拷贝字符串, 内存拷贝可以拷贝任何内容
memcpy(str + 1,"iii" , 3);
printf("%s\n", str);
3.内存比较
参数1和参数2: 要比较两块内存
参数3: 比较多少字节
返回值: 如果两个内存完全一样, 返回0, 如果不一样, 就把不一样的内存内容取差值返回
int result = memcmp(str, "aaa", 3);
printf("%d", result);
练习:定义两个整型指针,分别用malloc、calloc对其分配空间保存3个元素,malloc分配的空间用memset清零,随机对数组进行赋值随机范 围1-3,赋值后用memcmp比较两个数组。如果相同打印Good!否则 打印Failed...
int *p = malloc(sizeof(int) * 3);
int *pp = calloc(3, sizeof(int));
memset(p, 0, 12);
for (int i = 0; i < 3; i++) {
*(p + i) = arc4random() % 3 + 1;
*(pp + i) = arc4random() % 3 + 1;
}
if (memcmp(pp, p, 12) != 0) {
printf("Good");
} else {
printf("Failed");
}
free(p);
free(pp);