ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

C语言杂记——动态内存

2019-07-03 21:54:24  阅读:192  来源: 互联网

标签:malloc int void pPrimes C语言 杂记 内存 动态内存 printf


动态内存

c语言还有一个功能:动态内存分配,它依赖指针的概念,为在代码中使用指针提供了很强的激励机制,它允许在执行程序时动态内存分配。
在CPU内部存在堆栈,堆区域用于动态分配内存,由程序员完全掌控。栈区域主要保存函数参数和局部变量。在执行完该函数后,存储参数和局部变量的存储空间会完全释放。

动态内存分配:malloc()函数

在运行时分配内存最简单的标准函数是malloc(),需要调用stdlib.h
函数原型:

_CRTIMP void * __cdecl malloc(size_t);  

参数说明:函数会返回一个void* 类型的指针;
动态内存分配的一条例子:

int *pNumber = (int *)malloc(100);

返回的void*类型的数据能指向任意的类型的指针,然而不能取消对void指针的引用;因此,将void*转换成int*,防止报错。
如果因为某种原因分配内存失败,malloc()会返回NULL

int *pNumber = (int *)malloc(100);
if(!pNumber)
{
	//分配内存失败;
}

释放动态内存

在动态分配内存时,应该在不需要时,释放掉内存空间;如果未能及时释放,会造成内存泄漏;堆上的内存会在程序结束时,自动释放内存。

内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

要释放动态分配的内存,必须能访问到引用的内存块的地址。

free(pNumber);
pNumber = NULL;

在释放指针指向的堆内存时,必须确保它不被另一个地址覆盖;
代码示例:

#include <STDIO.H>
#include <stdlib.h>
#include <stdbool.h> 

int main(void)
{
	unsigned long long *pPrimes = NULL;
	unsigned long long trial;
	bool found = false;
	int total;
	int count;
	int i;
	printf("How many primes would you like - you'll get at least 4?");

	scanf("%d",&total);
	total = total < 4 ? 4 : total;

	pPrimes = (unsigned long long*)malloc(total*sizeof(unsigned long long));
	if(!pPrimes)
	{
		printf("end");
		return 1;
	}

	*pPrimes = 2ULL;
	*(pPrimes + 1 ) = 3ULL;
	*(pPrimes + 2 ) = 5ULL;

	count = 3;
	trial = 5ULL;

	while (count < total)
	{
		trial += 2ULL;
		for (i = 1;i < count;++i)
		{
			if (!(found = (trial % *(pPrimes + i))))
				break;
		}
		if(found)
			*(pPrimes + count++) = trial;
	}

	for ( i = 0; i < total; ++i)
	{
		printf("%100u",*(pPrimes + i));
		if(!(i+1)%5)
			printf("\n");
	}
	printf("\n");
	free(pPrimes);
	pPrimes = NULL;
	return 0;
} 

How many primes would you like - you’ll get at least 4?25
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
请按任意键继续. . .

用calloc()函数分配内存

stdlib.h头文件中声明的calloc()函数相比于malloc()函数有两个优点:第一,把内存分配给固定大小的数组;第二,初始化了所分配的内存,所有位为0;
函数原型

_CRTIMP void * __cdecl calloc(size_t, size_t);

它的用法与malloc()相似

int *pNumber = (int *)calloc(75,sizeof(int));//申请了75个int类型的内存
if(!pNumber)
{
	//分配内存失败;
}

拓展动态内存

realloc()函数可以重用或拓展以前用malloc()calloc()(或者realloc())分配的内存。
realloc()函数需要两个参数,一个是包含地址的指针,该地址由malloc()calloc()或者realloc()返回;另一个是重新分配的字节数;
代码示例:

#include <STDIO.H>
#include <STDLIB.H>
int main(void)
{
	char*p  = NULL;
	p=(char*)malloc(100);

	if(p)
		printf("MemoryAllocatedat:%x\n",p);
	else
		printf("NotEnoughMemory!\n");

	getchar();
	p=(char*)realloc(p,256);
	if(p)
		printf("MemoryReallocatedat:%x\n",p);
	else
		printf("NotEnoughMemory!\n");

	free(p);
	p = NULL;
	return 0;
}

MemoryAllocatedat:6b1160
MemoryReallocatedat:6b1030
Press any key to continue

使用动态分配的基本原则

  • 避免分配大量的小内存块。分配堆上的内存需要一定的系统开销,所以分配多给小的内存块比分配几个大的内存块开销要大;
  • 仅在需要的时候分配.只要堆上使用完了内存块,就释放它;
  • 总是确保释放已分配的内存。
  • 在释放内存之前,确保不会无意中覆盖堆上已分配的内存的地址,负责程序会出现内存泄漏。

标签:malloc,int,void,pPrimes,C语言,杂记,内存,动态内存,printf
来源: https://blog.csdn.net/qq_41423110/article/details/94590633

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有