动态内存的深度剖析

上次我们学习了动态内存函数,今天我们要更深一层次的研究学习它。

一。常见的动态内存错误。

(1)对NULL指针的解引用操作。

void test()
{
int *p=(int*)malloc(INT_MAX/4);
*p=20;//如果p的值是NULL,就会有问题
free(p);

解析:没有判断p是否为空,因为只要用malloc开辟空间就需要判空,要不然会出错。

(2)对动态开辟空间的越界访问。

void test()
{
int i=0;
int *p=(int *)malloc(10*sizeof(int));
if(NULL==p)
{
exit(EXIT_FAILURE);
}
for(I=0;i<=10;i++)
{
*(p+i)=I;//当I是10的时候越界访问。
}
free(p);
}

解析:只开辟了10个空间,但是却用了11个,所以越界访问了。

(3)对非动态开辟内存使用free释放。

void test()
{
int a=10;
int *p=&a;
free(p);
}

解析:因为p实在栈上开辟的,但是free只能释放堆上的。

(4)使用free释放一块动态开辟内存的一部分。

void test()
{
int *p=(int *)malloc(100);
p++;
free(p);//p不在指向动态内存的初始位置。
}

解析:p必须要整体释放,不能局部释放,而且也没有进行判空。


(5)对同一块动态内存多次释放。

void test()
{
int *p=(int *)malloc(100);
free(p);
free(p);
}
解析:重复释放。

(6)动态开辟内存忘记释放(内存泄漏)

void test()
{
int *p=(int *)malloc(100);
if(NULL!=p)
{
*p=20;
}
}
int main()
{
test();
while(1);
}

解析:没有用free释放,会造成内存泄漏。



二。接下来我们再来看一些经典的笔试题。

(1)

void GetMemory(char *p)
{
	p=(char *)malloc(100);
}
void Test(void)
{
	char *str=NULL;
	GetMetmory(str);
	strcpy(str,"hello world");
	printf(str);
}
解析:p是在调用函数时产生的临时变量,这时str传给p的是它的值,是给p在堆上用malloc,与str没关系,所以函数退出之后p就会被释放,所以发生了内存泄漏,这时str还是空,所以本题打印不出来字符串,会崩溃。如图:
(2)
char *GetMemory(void)
{
	char p[]="hello world";
	return p;
}
void Test(void)
{
	char *str=NULL;
	str=GetMemory();
	printf(str);
}

解析:p是一个临时变量,调用完就会被释放,虽然被释放但是它并没有被清空,可是却被新调用的printf函数的栈帧覆盖了,所以最后还是打印不出来。

(3)

void GetMemory(char **p,int num)
{
	*p=(char *)malloc(num);
}
void Test(void);
{
	char *str=NULL;
	GetMemory(&str,100);
	strcpy(str,"hello");
	printf(str);
}

解析:当运用malloc在堆上开辟空间时,必须要判空,而且本题没有释放p,所以会产生内存泄漏。


(4)

void Test(void);
{
	char *str=(char *)malloc(num);
	strcpy(str,"hello");
	free(str);
	if(str!=NULL)
	{
		strcpy(str,"world");
		printf(str);
	}
}

解析:释放str后,str肯定不为空,所以条件肯定成立,而且没对malloc判空。


三。柔性数组:结构中的最后一个元素允许是未知大小的数组。

1柔性数组的特点

(1)结构中的柔性数组成员面前必须至少有一个其它成员。

(2)sizeof返回的这种结构大小不包括柔性数组的内存。

(3)包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的与其大小。

typedef struct st_type
{
	int i;
	int a[];
}type_a;
printf("%d\n",sizeof(type_a));

此时结构体的大小为4,柔性数组成员不占空间大小。

2。柔性数组的优点

(1)方便内存释放。

(2)这样有利于访问速度。

 
 



猜你喜欢

转载自blog.csdn.net/ymk1507050118/article/details/80490356