静态内存和动态内存

静态内存的缺点(以传统数组说明)

1, 数组长度必须事先指定,只能是常整数, 不能是变量

    1) int a[5] ; // OK

    2) int len = 5; int a[len];  // error

2, 传统数组(静态数组), 其内存 程序员无法手动释放. 在一个函数运行期间, 系统为该函数中数组分配的空间会一直存在,直到该函数运行完毕, 数组的空间才会被系统释放.

3, 数组的长度一旦定义, 就不能再更改, 即无法在函数运行期间动态的扩充和缩小.

4, 无法跨函数使用, 即A函数中的数组, 在A运行时才可以被B函数使用.


动态内存的出现很好的解决了传统数组以上的缺陷.

/*
	malloc : memory allocate.该函数指定的内存是动态的
*/
#include <stdio.h>
#include <malloc.h>

void initVars(int * p, int count) {
	int i;
	for (i = 0; i < count; i++) {
		*(p + i) = i;
	}
}
void printVars(int * p, int count) {
	int i;
	for (i = 0; i < count; i++) {
		printf("%d, ", *(p + i));
	}
}

int main(void) {

	// 分配了 4个字节, 静态分配, 直到main函数结束,由系统释放
	int i = 5;

	/*
		1, 头文件: malloc.h
		2, malloc(int size)
		3, size: 整型, 请求系统为本程序分配的字节数
		4, malloc函数 返回 首字节的地址.
		5, (int * ) : 强转, 声明 这 4*10 个字节 分配给10个int类型变量
		6, 指针变量占4个字节, 指针变量指向的内存 占4*10个字节
		7, 指针变量本身所占的内存是静态分配的, 但其指向的内存是动态分配的.

	 */
	int * p = ( int * ) malloc(4 * 10);	// 4字节一划分, 10个,
	char * q = ( char * ) malloc(4 * 10);// 1字节一划分, 40个

	initVars(p, 10);	// 赋值
	printVars(p, 10);	// 打印

	free(p); // 表示把p指向的内存释放掉
	free(q);

	return 0;
}


一维数组的构建

静态内存和动态内存_第1张图片


/*
 	 动态构造一维数组, 动态构造, 静态使用
 	1) 长度无需预先指定
 	2) 运行期, 可扩充和缩小.void *realloc(void *mem_address, unsigned int newsize);
 	3) 可手动释放
 */
#include <stdio.h>
#include <malloc.h>

int main(void) {
	// 静态构造一维数组
	int a[5]; // sizeof(int) = 4; 分配了 20个字节. 静态数组

	int len = 3; // 长度, 可用 scanf() 指定
	// 动态构造一维数组
	int * pArr = (int *) malloc( sizeof(int) * len );

	// 赋值
	int i;
	for (i = 0; i < len; i++) {
		scanf("%d", pArr + i);
	}
	// 打印
	for (i = 0; i < len; i++) {
		printf("%d \n", pArr[i]);
	}

	// 扩充, 保留已有的
	realloc(pArr, 5);

	// 缩小, 砍掉多余的
	realloc(pArr, 2);

	// 释放 动态数组
	free(pArr);

	return 0;
}

动态内存和静态内存的比较

1, 静态内存是由系统自动分配的, 有系统自动释放

    静态内存是在栈分配的
2, 动态内存时程序员手动分配, 手动释放(只分配不释放, 就是内存泄露)
    动态内存时在堆分配的


 多级指针

int main(void) {

	int i = 10;			// 变量i	, 存数值

	int * p = &i;		// 存int 类型 变量的地址

	int ** q = &p;		// 存int* 类型 变量的地址

	int *** r = &q;		// 存int** 类型 变量的地址

	// i
	printf("i = %d \n", i);
	printf("i = %d \n", *p);
	printf("i = %d \n", **q);
	printf("i = %d \n", ***r);

	return 0;
}
静态内存和动态内存_第2张图片

跨函数使用内存

// 函数g 执行完毕, 为其分配的所有静态内存都会释放
// 即静态变量, 所在的函数终止后, 无法再被使用.
void g_1(int ** q) {
	int i = 10;
	*q = &i;	// p = &i;
}

//内存越界, 使用了不该使用的内存
void f_1() {
	int i = 9;
	int * p = &i;
	g_1(&p);	// p指向了一块没有访问权限的内存(被释放的内存)
	printf("%d \n", *p);	// 10
}

// 在该函数内造出一块空间, 且其他的函数可以使用
void g_2(int ** q) {
	*q = (int *) malloc( sizeof(int) ); //  p 指向了一块4字节的空间
	**q = 5;
}
// 使用动态内存
void f_2() {
	int * p;

	g_2(&p);
	printf("%d \n", *p);

	free(p);
}


你可能感兴趣的:(静态内存和动态内存)