C语言 动态内存分配机制(堆区) int*p=malloc(5*sizeof)

Posted DQ_CODING

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言 动态内存分配机制(堆区) int*p=malloc(5*sizeof)相关的知识,希望对你有一定的参考价值。

C程序内存分配图

栈区:局部变量
堆区:动态分配的数据
静态存储区/全局区:全局变量,静态数据
代码区:代码,指令

内存分配说明

内存动态分配的相关函数

堆区:
#inlcude<stdlib.h>

Malloc(size);//分配长度为size个字节的连续空间

Calloc(n,size);//分配size个长度为n个字节的连续空间,总共有size*n个字节

Free§;//销毁指针p所指向的堆空间,其他函数和主函数不能再使用

Realloc(p,size);//重新分配指针p所指向的内存空间大小,指针所指向的地址不变,仅仅是空间扩大或缩小

Void*:

Void*:仅仅是一个纯地址,而不指向任何的对象:
Void* p;//无类型指针变量
如果是void类型,不能够用p来取得值(报错)

void*强制类型转换举例:

代码

#include<stdio.h>
//动态内存分配(堆区)--void*无类型指针

int main()
{
	int a=102;
	int *pa=&a;

	//类型转换1
	char b='c';
	char *pb=&b;
	void *p;
	char *pc;
	char *pd;
	p=(void*)pb;//强制类型转换,char*pb-->void*,并把pb地址赋值给p
	pc=(char*)p;//强制类型转换,void*p-->char*
	pd=(char*)pa;

	//记住:没有*p,p只是一个地址,不指向任何对象
	printf("类型转换1:\\n");
	printf("pb=%c address=%p self-address=%p\\n",*pb,pb,&pb);
	printf("p:address=%p self-address=%p\\n",p,&p);
	printf("pc=%c address=%p self-address=%p\\n",*pc,pc,&pc);
	printf("pd=%c address=%p self-address=%p\\n",*pd,pd,&pd);

	
	getchar();
	return 0;
}

说明:
在C99的编译器中,其他类型转void*类型,是自动类型转换:
int a=2;
void *p=&a;
低版本的则需要强制类型转换:
void *p=(void *)&a;

应用案例

代码

#include<stdio.h>
#include<stdlib.h>
//动态内存分配(堆区)--malloc()函数
//输出所有成绩中小于60的成绩
#define SIZE 5
void check(int *p,int len);//函数原型,函数声明
int *check1(int *p,int len);

int main()
{
	int *p=(int*)malloc(5*sizeof(int));//开辟5*4大小的空间,相当于一个长度为8的数组
	int i=0;
	//*p=-842150451是一个垃圾值,堆区的第一个字节,4个字节才存储一个元素,因此不能使用*p
	printf("address=%p self-address=%p\\n",*p,p,&p);
	printf("输入每一个成绩:\\n");
	while(i<5)
	{
		//p+i=arr[0]+i的地址
		//通过数组的地址来为数组每一个元素赋值
		scanf("%d",p+i);
		i++;

	}
	printf("方式1:\\n");
	//输出成绩1
	check(p,5);


	//输出成绩2
	int*k=check1(p,5);
	printf("\\n方式2:\\n");
	for(i=0;i<5;i++)
	{
		if(*k!=0)
		{
			printf("%d",*k);
			k++;
		}

	}

	getchar();//enter
	getchar();
	return 0;
}
void check(int *p,int len)
{
	int i;

	for(i=0;i<len;i++)
	{
		if(p[i]<60)
		{
			printf("%d ",p[i]);
		}
	}

}

int *check1(int *p,int len)
{
	static int i,j=0,arr[SIZE];//局部数据,使用静态static

	for(i=0;i<len;i++)
	{
		if(p[i]<60)
		{
			arr[j++]=p[i];

		}
	}

	return arr;
}

图示

练习–逆序输出字符串

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//动态内存分配(堆区)--函数练习
//malloc()分配内存空间
//realloc()重新分配内存空间
//free()释放内存空间

char *reverse(char *s,int len);//函数声明
//逆序打印字符串
const int size=100;
int main()
{
	char *p=(char*)malloc(size*sizeof(char));//为p动态分配内存空间
	char s[size];
	gets(s);
	int len=strlen(s);
	char *p=(char*)realloc(p,len*sizeof(char));//重新为p分配更合适的内存空间
	
	//p=k[0]的地址(char*)
	p=reverse(s,len);
	int i;
	for(i=0;i<len;i++)
	{
		printf("%c",*p+i);
		//或p++
		
	}
	free(p);//释放p所指向的内存空间
	getchar();//enter
	getchar();
	return 0;
}
//逆序字符串
char *reverse(char *s,int len)
{
	int i=len-1,j=0;
	static char k[size];
	while(i>=0)
	{
		k[j++]=s[i];
		i--;
	}
	return k;
}

基本原则

1)每开辟一个内存就会占用系统开销,所以需要避免分配大量小内存块
2)内存泄漏:没有释放内存空间,这一个内存空间就会一直被占用
3)开辟了动态内存后一定要记得释放:谁分配,谁释放

指针使用一览

指针数组:
由n个指向整型元素的指针而组成,里面存放指针
Int *ptr[3];

数组指针:
指向一个有n个元素的数组的指针,里面存放的是整型变量(int类型长度为n的数组的首地址),存的是一个数组地址,而不是单个元素
int(*p)[n]

int (*p)(int ,int):指向函数的指针

以上是关于C语言 动态内存分配机制(堆区) int*p=malloc(5*sizeof)的主要内容,如果未能解决你的问题,请参考以下文章

c语言 动态内存规划

C语言内存四区的学习总结---- 堆区

怎么查看动态分配内存空间的大小(c语言)。

C语言中定义的静态变量存放在栈区,动态分配的内存空间位于堆区。

内存四区模型

在C语言中,如何给函数分配内存?