当前位置:首页 » 《随便一记》 » 正文

C语言动态内存开辟_Ja_king_的博客

15 人参与  2022年02月19日 08:36  分类 : 《随便一记》  评论

点击全文阅读


动态内存开辟

    • 1.malloc、free
      • 1.1 malloc的原型为:
      • 1.2 malloc的用法:
      • 1.3 free的原型:
      • 1.4 free的用法:
    • 2.calloc
      • 2.1 calloc原型:
      • 2.2 calloc用法:
    • 3.realloc
      • 3.1 realloc原型:
      • 3.2 realloc用法:

1.malloc、free

1.1 malloc的原型为:

void *malloc( size_t size );

1.2 malloc的用法:

看下面代码:

int* p=(int*)malloc(10*sizeof(int));

上面代码意思是开辟10个int类型大小的空间,将其强制转换为int型,并用int类型指针接收。
1.若开辟成功,则返回开辟空间的头指针。
2.若开辟失败,则返回空指针。
所以,用了malloc后一定要判断!
如下面代码:

#include<stdio.h>
#include<stdlib.h>// malloc 所在头文件
#include<errno.h>// errno,h 错误码库
int main()       // 与 函数 strerror(错误信息报告)  搭配使用,将错误码转化为错误信息,并返回它的地址
{
	// 我想向内存申请 10个 整形的 空间
	int* p = (int*)malloc(/*INT_MAX*/10 * (sizeof(int)));// 因为  malloc 函数 返回的是 万能*(无类型)指针,所以需要转化类型
	// malloc 函数 也有 开辟空间失败的时候,
	// 比如 内存 只有 4 个 g ,我要开辟 8 g 空间,这肯定是会失败的,返回 空指针 NULL
	
	if (p == NULL)
	{
		// 找出打印错误原因的方式
		printf("%s\n", strerror(errno));// malloc(INT_MAX)
		                //输出 Not enough space
	}
	else
	{
		// 正常使用 空间
		int i = 0;
		for (i = 0; i < 10; i++)
		{
			*(p + i) = i;// 赋值 0 1 2 3 4 5 6 7 8 9
		}
		for (i = 0; i < 10; i++)
		{
			printf("%d ", *(p + i));// 输出 0 1 2 3 4 5 6 7 8 9
		}
		printf("\n");
	}
	// 当动态申请的空间 不再使用的时候
	// 就会把空间 还给 操作系统
	// 这时候 就会用到 free 函数
	return 0;
}

而malloc的使用需和free一起,即:用malloc开辟一处空间,必须由free来释放。否则会造成内存泄露!

1.3 free的原型:

void free( void *memblock );

1.4 free的用法:

free专门用于动态内存的释放和回收。如下代码:

#include<stdio.h>
#include<stdlib.h>// malloc,free 所在头文件
#include<errno.h>
int main()
{
	// 我想向内存申请 10个 整形的 空间
	int* p = (int*)malloc(10 * (sizeof(int)));
	if (p == NULL)
	{
		// 找出打印错误原因的方式
		printf("%s\n", strerror(errno));// malloc(INT_MAX)
		                //输出 Not enough space
	}
	else
	{
		// 正常使用 空间
		int i = 0;
		for (i = 0; i < 10; i++)
		{
			*(p + i) = i;// 0 1 2 3 4 5 6 7 8 9
		}
		for (i = 0; i < 10; i++)
		{
			printf("%d ", *(p + i));// 0 1 2 3 4 5 6 7 8 9
		}
		printf("\n");
	}
	// 当动态申请的空间 不再使用的时候
	// 就会把空间 还给 操作系统
	// 这时候 就会用到 free 函数
	free(p);// 用完了再释放,也就是说 在打印完之后(调用完之后),再释放(p的值没有改变,还可以通过它找到该空间)
	//  虽然当前空间 不属于当前程序,但是依然 可以通过 p  找到  该空间,很有可能会破坏这个空间
	//  所以先在这个 指针 依然很危险

	p = NULL; // free函数 释放完空间后,不会改 p 的值,所以我们自己主动改
	return 0;
}
// 最后请注意:free 是用来 释放 动态开辟的内存

// free 函数 的 特殊情况:
//1. 如果参数 ptr 指向的空间不是动态开辟的,那 free 函数的行为是未定义的
//2. 如果参数 ptr 是 NULL 指针,则函数 什么 都不做。

1.首先,将动态开辟的空间free掉。
2.再将free掉的空间的头指针制为空即可。

2.calloc

2.1 calloc原型:

void *calloc( size_t num, size_t size );

2.2 calloc用法:

calloc和malloc一样,都用于动态内存开辟,区别点在于calloc具有初始化功能,即:calloc可将开辟的空间进行初始化操作。
如下代码:

 用法跟 malloc 函数差不多
#include<stdio.h>
#include<errno.h>
#include<string.h>
int main()
{                     // 开一块空间,空间大小为 10 * int == 40 字节
	int* p = (int*)calloc(10, sizeof(int));// 比 malloc 函数 多一个元素个数 参数
	if (p == NULL)    
	{
		printf("%s\n", strerror(errno));
	}
	else
	{
		int i = 0;
		for (i = 0; i < 10; i++)// 因为 p 为整形指针变量,指向一个 int 类型 元素,所以有 10个 int 元素
		{
			printf("%d ", *(p + i));// 0 0 0 0 0 0 0 0 0 0
		}  //calloc 在开辟好空间后,会把空间的所有字节内容全部初始化为 零
	}
	free(p);
	p = NULL;// 狗头拿来!!
	return 0;
}

3.realloc

3.1 realloc原型:

void *realloc( void *memblock, size_t size );

3.2 realloc用法:

有时我们会发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,为了合理的使用内存,我们一定会对内存的大小做灵活的调整,realloc函数就可以做到对动态开辟内存大小的调整。
如以下代码:

#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char* argv[], char* envp[])
{
	int input;
	int n;
	int *numbers1;
	int *numbers2;
	numbers1=NULL;
 
	if((numbers2=(int *)malloc(5*sizeof(int)))==NULL)//为numbers2在堆中分配内存空间
	{
		printf("malloc memory unsuccessful");
		exit(1);
	}
	
	printf("numbers2 addr: %8X\n",(int)numbers2);
 
	for(n=0;n<5;n++) //初始化
	{
		*(numbers2+n)=n;
		//printf("numbers2's data: %d\n",*(numbers2+n));
	}
 
	printf("Enter new size: ");
	scanf("%d",&input);
 
	//重新分配内存空间,如果分配成功的话,就释放numbers2指针,
	//但是并没有将numbers2指针赋为NULL,也就是说释放掉的是系统分配的堆空间,
	//和该指针没有直接的关系,现在仍然可以用numbers2来访问这部分堆空间,但是
	//现在的堆空间已经不属于该进程的了。
	numbers1=(int *)realloc(numbers2,(input+5)*sizeof(int));
 
	if(numbers1==NULL)
	{
		printf("Error (re)allocating memory");
		exit(1);
	}
	
	printf("numbers1 addr: %8X\n",(int)numbers1);
 
	/*for(n=0;n<5;n++) //输出从numbers2拷贝来的数据
	{
		printf("the numbers1's data copy from numbers2: %d\n",*(numbers1+n));
	}*/
 
	for(n=0;n<input;n++)//新数据初始化
	{
		*(numbers1+5+n)=n+5;
		//printf("numbers1' new data: %d\n",*(numbers1+5+n));
	}
 
	printf("\n");
 
	free(numbers1);//释放numbers1,此处不需要释放numbers1,因为在realloc()时已经释放
	numbers1=NULL;
	//free(numbers2);//不能再次释放
	return 0;
}

1.如果当前内存段后有足够的空间,realloc()返回原来的指针。
2.如果当前内存段后没有足够的空间,realloc()返回一个新的内存段的指针


点击全文阅读


本文链接:http://zhangshiyu.com/post/34964.html

空间  开辟  指针  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1