C语言中的动态内存分配

一、动态分配内存知识

动态内存分配:程序在运行的时候用malloc等函数在堆上申请任意多少连续的内存,程序员自己负责在何时用free释放内存。

动态内存分配的生存期由我们自己决定,使用非常灵活,但是问题相对也比较多;

如果没有释放的话,很容易就会造成内存溢出,因为堆中的内存块是全局的,因此不会因为函数的调用而结束。

二、动态分配内存的函数

动态分配内存的主要使用的函数有malloc,calloc,realloc,free包含在malloc.h或stdlib.h头文件中

1.malloc

void *malloc(size_t size) //返回的是一个通用类型的指针,根据需要去进行强转;

功能:允许从空闲内存池中分配连续内存但不初始化

参数:size参数实际就是一个所需字节数的整数

返回:若分配成功则返回一个指向该内存块的指针,在使用时可根据需要做强制类型转换,否则返回NULL(空指针)//需要判空

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

//筛选法求素数
void SiftPrime(int n)
{

	int *p = (int *)malloc(n*sizeof(int));//等同int p[n];
	assert(p != NULL);//判断指针p是否为空
	if(p == NULL)
	{
		return ;
	}

	int i;
	for(i=0;i<n;i++)//所有的数标记为1
	{
		p[i] = 1;
	}

	p[0] = p[1] = 0;

	for(i=2;i<n;i++)
	{
		for(int j=i+1;j<n;j++)
		{
			if(j%i == 0)
			{
				p[j] = 0;//如果是不是素数则标记为0
			}
		}
	}

	for(i=0;i<n;i++)//输出标记为1的数,即为素数
	{
		if(p[i] != 0)
		{
			printf("%d\n",i);
		}
	}
}

int main()
{
	SiftPrime(20);
	return 0;
}

特别解释一下int *p = (int *)malloc(n*sizeof(int));

这条语句就是申请n*sizeof(int)这么长字节则内存,强转为int*,赋值给设置的整形指针变量p

2.calloc

void *colloc(size_t num_elements,size_t element_size);

功能:功能同malloc是一样的,但是作初始化

参数:num_elements是所需的元素的数量,element_size是每个元素的字节数

返回:同malloc函数一样

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int main()
{
	/*//如下操作等同calloc
	int *arr = (int *)malloc(10*sizeof(int));
	for(int i=0;i<10;i++)
	{
		arr[i] = 0;
	}*/
	int *arr = (int *)calloc(10,sizeof(int));//0,0,0,

	return 0;
}

3.realloc

void *realloc(void *ptr,size_t new_size);

功能:在指针ptr指向的内存基础上扩大或者缩小内存

参数:ptr是指向先前通过malloc,calloc和realloc函数后分配的内存块的指针,new_size是内存块的新尺寸(可以小于原尺寸)

int main()
{
	int *p = (int *)realloc(p,10*sizeof(int));
	//下面的代码等同realloc
	int *q = (int *)malloc(20*sizeof(int));
	for(int i=0;i<10;i++)
	{
		q[i] = p[i];
	}

	p = q;
	q = NULL;

	return 0;
}

特别注意

1:当扩展内存的时候,不会对添加进内存块的字节进行初始化

2:若不能调整内存则返回NULL,但原有内存中的数据是不会发生改变的

3:若第一个参数为NULL那么功能 等同与malloc函数,若第二个参数为0,那么会释放调用内存块

realloc(NULL,10*size(int)) //等同malloc(10*sizeof(int));
realloc(p,0); //等同于free

4.free

功 能: 与分配函数配对使用,释放函数申请的动态内存。

(另:对于free(p)这句语句,如果p 是NULL 指针那么free 对p 无论操作多少次都不会出问题。如果p 不是NULL 指针,那么free 对p连续操作两次就会导致程序运行错误。)

用 法: void free(void *ptr);

free释放内存,不使用free则会出现内存泄漏,所以malloc下面的代码段出现了内存泄漏

free崩溃的原因

1、越界.漏写sizeof,realloc第二个参数写错

2、修改了指针的指向,p++

3、重复释放同一段内存

4、释放非动态内存

猜你喜欢

转载自blog.csdn.net/hdong99/article/details/80092166