C语言编程入门——动态内存分配

内存管理,是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。内存管理是C语言编程中重要的组成部分,C语言中的内存需要手动分配,手动释放,一般遵循分配多少,释放多少,以免造成内存泄漏。内存管理是一项重要且复杂的事情,理解内存管理,对后面课程及项目的学习会有很大的作用。

之前创建变量,是系统自动分配的内存,放在栈内存中,销毁后被系统自动回收,手动分配的内存,放在堆内存中,需要手动释放。千万不要忘记销毁对象手动将内存释放并将指针置空(NULL)。

内存分配常用头文件:malloc.h

malloc函数:

# include <stdio.h>
# include <malloc.h>

int main(void)
{
	int i = 3; //静态分配内存,给变量i分配了4个字节空间。
	int * p = (int *)malloc(20);
						/*
							1. 动态分配内存,要使用malloc函数,必须添加malloc.h头文件。malloc是 memory(内存) 							   allocate(分配)的缩写。
							2. malloc函数只有一个形参,并且形参是整型。
							3. 20表示请求系统为本程序分配20个字节内存空间。
							4. malloc函数的返回值为第一个字节的内存地址,赋值给指针变量p。
							   malloc函数的返回值为void * 类型,void * 类型也叫干地址,即无实际意义的地址。
							   并且需要强制类型转换(int *),将所分配的内存转换为指针变量p所定义的int * 类型。
							   共分配了20个字节,每个int类型变量占4个字节,所以共生成了5个变量(动态数组)。
							   第一个变量为*p,第二个为*(p+1),依次类推,第i个为*(p+i)。
							5. 注意:指针变量p所占的内存是4个字节,为静态分配的,p所指向的内存为动态分配的。
						*/

	*p = 3; //为第一个变量赋值3
	*(p+1) = 5; //为第二个变量赋值5

	printf("%d, %d\n", *p, *(p+1));

	free(p); //free()函数,将p指向的内存空间释放掉。注意:p本身的内存空间是静态的,不会被释放,只能在程序结束后被系统释放。

	return 0;
}

静态分配内存:

# include <stdio.h>
# include <malloc.h>

int main(void)
{
	printf("呵呵!\n");

	while (true)
	{
		int * p = (int *)malloc(100);  //无限循环分配内存
	}

	return 0;
}

free函数:

# include <stdio.h>
# include <malloc.h> //free()函数也位于malloc.h头文件中,所以要声明。

int main(void)
{
	int i = 3;
	int * p = &i;

	free(p); //p所指向的变量i的内存是静态分配的,不能够手动释放,这样写会出错。

	printf("%d\n", i);

	return 0;
}

//运行直接报错

动态构造一维数组:

# include <stdio.h>
# include <malloc.h>

int main(void)
{
	int a[5]; //静态构造了5个元素的一维数组。
	int * pArr;
	int len;
	int i;

	printf("请输入需要存放的元素的个数:");
	scanf("%d", &len);
	pArr = (int *)malloc(4*len); //动态构造了一维数组,长度为len,数组类型为int类型,数组名即为pArr。类似于 int a[5]; 数组名PArr与a相同。
								 //动态数组的操作与静态数组相同,数组名pArr存放了数组第一个元素的地址。

	for (i=0; i<len; ++i)
	{
		printf("请输入第%d个元素的值:", i);
		scanf("%d", &pArr[i]); //与静态数组操作相同。
	}

	printf("一维数组中的内容为:\n");
	for (i=0; i<len; ++i)
		printf("a[%d] = %d\n", i, pArr[i]);

	realloc(pArr,100); //realloc()重新分配内存函数,用于改变数组的长度,后跟两个参数,第一个是数组名,第二个是重新分配的数组字节数,
					   //如此函数即将pArr数组所占内存改为100字节。
					   //当内存改变时,增长:如50字节变为100字节,前50字节内容保留不变,再增加50字节内存。
					   //			   缩小:如150字节变为100字节,前100字节内容保留,后50字节内容丢失。

	free(pArr); //free()函数释放指针变量所指向的变量内存,当释放数组名时,将全部释放整个数组所占的内存,而不是只释放数组名所指向的第一个元素变量内存。

	printf("一维数组中的内容为:\n");
	for (i=0; i<len; ++i)
		printf("a[%d] = %d\n", i, pArr[i]);

	return 0;
}

动态内存跨函数使用:

将指针变量传递过去

# include <stdio.h>

void f(int ** q)
{
	int i = 5;

	*q = &i;

	return;
}

int main(void)
{
	int * p;

	f(&p);

	printf("%d\n", *p); //这样写逻辑上是错误的,因为函数f()已经运行结束,p所指向的变量i已经释放,不存在了,不能够再读取输出。
						//程序没有报错的原因是因为此软件(VC++6.0)比较弱智。

	return 0;
}

动态内存跨函数使用2:

/*
	2013年1月27日21:05:44
	动态内存的跨函数使用  (在使用时都需要传址)
	在main()函数中构造
	在change()函数中赋值
	在printf()函数中输出
*/

# include <stdio.h>
# include <malloc.h>

void change(int * q)
{
	*q = 10;

	return;
}

void printf(int * r)
{
	printf("%d\n", *r);

	return;
}

int main(void)
{
	int * p = (int *)malloc(sizeof(int)); //构造动态内存变量。
	*p = 3;

	change(p);
	printf(p);

	return 0;
}

练习示例:

# include <stdio.h>
# include <malloc.h>

int main(void)
{
	double i = 66.6;
	double * p = &i;

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

	p = (double *)malloc(sizeof(double));
	*p = 88.8; 

	free(p);
	free(p); //指针变量p所指向的内存空间不能被重复释放,即野指针不能再被释放,会导致出错。

	return 0;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-22 19:01:10

C语言编程入门——动态内存分配的相关文章

C语言学习笔记--动态内存分配

1. 动态内存分配的意义 (1)C 语言中的一切操作都是基于内存的. (2)变量和数组都是内存的别名. ①内存分配由编译器在编译期间决定 ②定义数组的时候必须指定数组长度 ③数组长度是在编译期就必须确定的 (3)但是程序运行的过程中,可能需要使用一些额外的内存空间 2. malloc 和 free 函数 (1)malloc 和 free 用于执行动态内存分配的释放 (2)malloc 所分配的是一块连续的内存 (3)malloc 以字节为单位,并且返回值不带任何的类型信息:void* mallo

C语言中的动态内存分配,malloc/free

malloc函数 原型 extern void *malloc(unsigned int num_bytes); 头文件 #include <stdlib.h> 功能 分配长度为num_bytes字节的内存块 返回值 如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL.当内存不再使用时,应使用free()函数将内存块释放.函数返回的指针一定要适当对齐,使其可以用于任何数据对象. 说明 关于该函数的原型,在以前malloc返回的是char型指针,新的ANS

指针 &amp;&amp; 动态内存分配

C++中的动态内存分配机制 c++中使用new和delete来完成在堆上对动态内存的分配和释放. 注.所有指针都应该被初始化 如果指针指向的动态内存被释放或没有指向合法的地址,就应该将指针设置为nullptr,否则内存泄漏. 变量: double* pvalue {}; pvalue=new double; *pvalue=9.0; 或 double* pvalue {}; pvalue=new double {9.0}; 或合并为一句 double* pvalue {new double{9.

动态内存分配与指向它的指针变量

1.动态内存分配的含义 c语言允许建立动态内存分配区域,以存放一些临时用的数据,这些数据不必再程序的声明部分定义,也不必等到函数结束时才释放,而是要随时开辟,不需要随时释放,这些数据是临时存放在一个特定的自由存储区(堆),可以根据需要向系统申请所需要大小的空间,由于未在声明部分定义它们为变量或数组,因此不能通过变量名或数组名去引用这些数据,只能通过指针来引用. 2.建立内存的动态分配 对内存的动态分配是通过系统提供的函数库来实现的,主要有malloc,calloc,free,realloc这四个

【C语言天天练(九)】动态内存分配

引言:数组的元素存储于内存中连续的位置上.当一个数组被声明时.它所须要的内存在编译时就被分配. 可是,我们能够使用动态内存分配在执行时为它分配内存. 一块内存的生命周期能够分为四个阶段:分配.初始化.使用.释放. 内存的分配一般使用C函数库里的malloc函数(原型:void *malloc(size_t size)). 关于malloc函数应该注意一下几点: 1.malloc的參数就是须要分配的内存的字节数. 2.malloc所分配的是一块连续的内存. 3.分配成功.则返回指向分配内存起始地址

数据结构基础(1)--数组C语言实现--动态内存分配

数据结构基础(1)--数组C语言实现--动态内存分配 基本思想:数组是最常用的数据结构,在内存中连续存储,可以静态初始化(int a[2]={1,2}),可以动态初始化 malloc(). 难点就是数组在删除或者插入元素的时候,要移动元素的坐标不好确定.规律: 1.如果要在数组中第pos个位置插入一个元素(应该从后面开始移动) for( i=cnu;i>=pos;i--) pBase[i]=pBase[i-1]; 2.删除数组第pos位置的元素 for(i=pos+1;i<=cnu;i--)

重拾c语言之动态内存分配

动态内存分配 传统数组的缺点: 1数组长度必须事先制定,且仅仅能是长整数不能是变量 2传统形式定义的数组该数组的内存程序无法手动释放 3数组一旦定义,系统就会为该数组分配的存储空间就会一直存在直到该函数执行结束 4数组的长度不能再函数的执行的过程中动态的扩充或者缩小 5不能跨函数使用 为什么须要动态分配内存 动态内存分配内存举例--动态数组的构造 静态内存分配和动态内存分配 跨函数使用内存的问题 #include<stdio.h> void f(void) { int a[5]={0,1,2,

动态内存分配(c语言)

当声明一个数组时,它所需要的内存将在编译时就被分配.但是,数组的长度在运行时才知道.它所需要的空间取决于输入的数据.所以,存在某一个数组实际所占的内存超过编译器所分配的内存.这时候,程序就会出现问题.所以,我们可以使用动态内存分配.所谓动态内存分配即为在运行时为它分配内存. 动态内存分配函数有:malloc,calloc,realloc,free. 函数所在的头文件:#include <stdlib.h> 函数原型: void *malloc( size_t size );//字节数 void

C语言程序编译的内存分配

C语言程序编译的内存分配: 1.栈区(stack) --编译器自动分配释放,主要存放函数的参数值,局部变量值等: 2.堆区(heap) --由程序员分配释放: 3.全局区或静态区 --存放全局变量和静态变量:程序结束时由系统释放,分为全局初始化区和全局未初始化区: 4.字符常量区 --常量字符串放与此,程序结束时由系统释放: 5.程序代码区--存放函数体的二进制代码 例: //main.c int a=0; //全局初始化区 char *p1; //全局未初始化区 void main() { i