C语言-内存管理

内存管理

内存分区

  • 常量区
  • 栈区
  • 全局区
  • 静态区
  • 堆区

常量区

  • 整形常量
  • 浮点常量
  • 字符常量
  • 字符串常量
  • 地址常量:数组名、函数名

特点:

不可修改

栈区

  1. 局部变量
  2. 函数形参

特点:

租来的房子,房子到期自动回收

  1. 访问速度快
  2. 空间少
  3. 生命周期和作用域从定义的位置开始到“}”结束

全局区

全局变量

特点:​

  1. 局部大于全局
  2. 默认初始化0
  3. 生命周期 程序开始到程序结束
  4. 作用域 整个项目

在其他文件中使用全局变量

/*a.c*/
extern int g_value;//全局变量的声明

void setValue(int g) {
	g_value = g;
}
/*main.c*/
#include <stdio.h>

int g_value = 100;

int main(int argc, char __ argv){
    setValue(200);
    printf("%d\n", g_value);
    return 0;
}

静态区

静态局部变量

特点:​

  1. 生命周期 程序开始到程序结束
  2. 作用域 从定义的开始到“}”结束
  3. 只被初始化一次

静态全局变量

#include <stdio.h>

void getValue(){
    static int s = 10;
    int n = 10;
    printf("%d ", s++);
    printf("%d ", n++);
}

int main(){
    getValue();//10 10
    getValue();//11 10
    return 0;
}

特点:

  1. 生命周期 程序开始到程序结束
  2. 作用域 当前文件

堆区

特点:​

自己买的房子,不会自动释放

  1. 不会自动释放
  2. 容量大
  3. 访问速度慢
  4. 堆区空间没有名字
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
    char *p = malloc(500);  // 在堆区分配500个字节的空间 => char p[500];
    p[0] = 'a';
    p[1] = 'c';
    strcpy(p, "abcdef");
    printf("%s", p);
    free(p);//不用时,一定手动释放空间
    return 0;
}

char *p = malloc(500); <==> char p[500];

GetMemory的几个笔试题

Getmemory的几个经典的关于内存的笔试题

输出结果以及出现的错误

Test1

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

p 是值传递,str不会被改变
修改方法:

  1. GetMemory1()返回值类型改为char *,返回堆区的地址,并用str接收
char* GetMemory1(void) {

	return (char *)malloc(100);

}

void Test1() {

	char* str = NULL;

	str = GetMemory1();

	strcpy(str, "hello world");

	printf(str);

	free(str);

	str = NULL;

}
  1. GetMemory1()的参数类型改为二级指针,传入str的地址即可
void GetMemory1(char** p) {

	*p = (char *)malloc(100);

}

void Test1() {

	char* str = NULL;

	GetMemory1(&str);

	strcpy(str, "hello world");

	printf(str);

	free(str);

	str = NULL;

}

Test2

char* GetMemory2() {
	char p[] = "hello world"; //p是局部变量
	return p; //试图返回局部变量的地址
}

void Test2() {
	char* str = NULL;
	str = GetMemory2();
	printf(str);
}

p中存放的是栈区的地址,函数结束后栈区数据被释放
修改方法:Test3 or Test4

Test3

char* GetMemory3() {
	char *p = "hello world"; //p是局部变量
	return p; //返回常量的地址
}

void Test3() {
	char* str = NULL;
	str = GetMemory3();
	printf(str);
}

输出:“hello world”

Test4

char* GetMemory4() {
	static char p[] = "hello world";
	return p;
}

void Test4() {
	char* str = NULL;
	str = GetMemory4();
	printf(str);
}

输出:“hello world”

Test5

void Test5() {
	char* str = (char*)malloc(100);
	strcpy(str, "hello");
	free(str); // 堆存放的数据释放
	//str = NULL //为了防止访问非法的空间,释放后,指向NULL
	if (str != NULL) {
		strcpy(str, "wold");
		printf(str);
	}
}

堆空间已经释放,访问非法
修改方法:

  1. free()移动到程序末尾

Test6

void Test6() {
	char* str = (char*)malloc(100);
	strcpy(str, "hello");
	str += 6;
	free(str); // str已经被修改 无法正常释放
	//str = NULL
	if (str != NULL) {
		strcpy(str, "wold");
		printf(str);
	}
}

释放时地址应和申请时的地址一致
修改方法:

  1. 删除str += 6;,并将free()移动到程序末尾

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值