关于GetMemory

关于GetMemory

C语言关于动态内存的相关库函数

1.malloc 函数 void *malloc( unsigned int size);
在内存的动态存储区中分配一块长度为"size" 字节的连续区域。

如果分配成功,则返回所分配内存空间的首地址,否则返回NULL,申请的内存不会进行初始化。

“类型说明符”表示把该区域用于何种数据类型。(类型说明符*)表示把返回值强制转换为该类型指针。

例如:pc=(char *) malloc (100);

2.calloc 函数 void *calloc(unsigned int num, unsigned int size)

按照所给的数据个数和数据类型所占字节数,分配一个 num * size 连续的空间。
函数返回该存储区的起始地址。

calloc申请内存空间后,会自动初始化内存空间为 0,但是malloc不会进行初始化,其内存空间存储的是一些随机数据。

calloc函数与malloc 函数的区别仅在于一次可以分配n块区域。

例如: ps=(struct stu*) calloc(2,sizeof (struct stu)); 其中的sizeof(struct stu)是求stu的结构长度。

3. realloc函数:void *realloc(void *ptr, unsigned int size)

动态分配一个长度为size的内存空间,并把内存空间的首地址赋值给ptr,把ptr内存空间调整为size。

申请的内存空间不会进行初始化。

例如:p1=(float *)realloc(p1,16);将原先开辟的8个字节调整为16个字节。

4.free函数: void free(void *ptr)
作用:释放由上面3种函数所申请的内存空间。

C++语言关于动态内存的相关操作符

C++语言中用new和delete来动态申请和释放内存。

1.申请单个对象p = new int(value);

2.动态申请数组int *p = new int [100];

3.释放空间

int *p, *q;
p=new int;
q=new int[10];
delete p;
delete [ ]q;

new和malloc的区别

  1. new/delete是C++关键字,需要编译器支持。malloc/free是库函数,需要头文件支持。
  2. 使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。
  3. new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。
  4. new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时返回NULL。
  5. new会先调用operator new函数,申请足够的内存(通常底层使用malloc实现)。然后调用类型的构造函数,初始化成员变量,最后返回自定义类型指针。delete先调用析构函数,然后调用operator delete函数释放内存(通常底层使用free实现)。
  6. C++允许重载new/delete操作符,特别的,布局new的就不需要为对象分配内存,而是指定了一个地址作为内存起始区域,new在这段内存上为对象调用构造函数完成初始化工作,并返回此地址。而malloc不允许重载。
  7. new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。自由存储区不等于堆,如上所述,布局new就可以不位于堆中。

下面看一道经典的面试题GetMemory

直接看代码

#include <iostream>
/************************************************************************/
/* 1、改变形参值,不会影响到实参,因此在Test1中GetMemory返回之后,str依然为NULL */
/* 2、strcpy不安全                                                      */
/* 3、malloc没有free内存泄露                                              */
/************************************************************************/
void GetMemory1(char *p)
{
	p = (char *)malloc(100);
}
void Test1(void)
{
	char *str = NULL;
	GetMemory1(str);
	strcpy(str, "hello world");  //这里str为NULL
	printf(str);
}


/************************************************************************/
/* 1、返回局部变量的指针,GetMemory返回时p已无效                            */
/************************************************************************/
char *GetMemory2(void)
{
	char p[] = "hello world";
	return p;
}
void Test2(void)
{
	char *str = NULL;
	str = GetMemory2();
	printf(str);
}


/************************************************************************/
/* 1、字面值存储在全局静态存储区,因此程序正常运行                            */
/* 2、设计概念有问题,并没有分配内存,始终返回同一个地址                       */
/* 3、c++11 会报错const char []”转换为“char *                             */
/*   return const_cast<char *>("hello world");							*/
/************************************************************************/
char *GetMemory3(void)
{
	return "hello world";
}
void Test3(void)
{
	char *str = NULL;
	str = GetMemory3();
	printf(str);
}


/************************************************************************/
/* 1、运行结果正确,形参传二级指针,实际是str的地址                          */
/* 2、malloc之后需要判断是否成功                                          */
/* 2、strcpy不安全                                                       */
/* 3、malloc没有free内存泄露                                              */
/************************************************************************/
void GetMemory4(char **p, int num)
{
	*p = (char *)malloc(num);
}

void Test4(void)
{
	char *str = NULL;
	GetMemory4(&str, 100);
	strcpy(str, "hello world");  
	printf(str);    
}


/************************************************************************/
/* 1、运行结果正常打印world,但是操作是非法的                                */  
/* 2、malloc之后需要判断是否成功                                           */
/* 3、strcpy不安全														*/ 
/************************************************************************/
void Test5(void)
{
	char *str = (char *) malloc(100);
	strcpy(str, "hello");
	free(str);    
	//str = NULL 这里应将str置NULL
	if(str != NULL)
	{
		strcpy(str, "world"); //这一步操作非法,free之后str指向的空间不再属于str
		printf(str); 
	}
}


/************************************************************************/
/* 1、程序崩溃,str+6之后free,操作了非法地址空间                            */  
/* 2、malloc之后需要判断是否成功                                           */
/* 3、strcpy不安全														*/
/************************************************************************/
void Test6()
{
	char *str=(char *)malloc(100);
	strcpy(str, "hello");
	str+=6;
	free(str);
	if(str!=NULL)
	{
		strcpy(str, "world");
		printf(str);
	}
}
int main()
{
	//Test1();
	//Test2();
	//Test3();
	//Test4();
	//Test5();
	Test6();

}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值