内存分配指针相关1

1.void GetMemory2(char **p,int num)
{
*p=(char *)malloc(num*sizeof(char));

}

int main(int argc, char *argv[])
{
char *str=NULL;
char str1[]="thank you.";
GetMemory2(&str, 100);
strcpy(str,"hello world!");
strcat(str,str1);
printf(str);
free(str);
return 0;
}

printf hello world!

 

编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是 _p,编译器使 _p = p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。在本例中,_p申请了新的内存,只是把 _p所指的内存地址改变了,但是p丝毫未变。所以函数GetMemory并不能输出任何东西。事实上,每执行一次GetMemory就会泄露一块内存,因为没有用free释放内存。

 

2. char *GetMemory2(int num)
{
 char *p=(char *)malloc(num*sizeof(char));      //在堆中分配
return p;
}

int main(int argc, char *argv[])
{
char *str=NULL;
char str1[]="thank you.";
str=GetMemory2(100);
strcpy(str,"hello world!");
strcat(str,str1);
printf(str);
free(str);
return 0;
}

输出同上

 不要用return语句返回指向“栈内存”的指针,因为该内存在函数结束时自动消亡;

 

 3.

char *str=NULL;
char str1[]="thank you.";
/*str=GetMemory2(100);
strcpy(str,"hello world!");
strcat(str,str1);*/

str=str1;
 在以上的程序段中修改str1的元素值,str的内容也做相应改变

在内存释放时,对指针进行free操作后,要将该指针置为空值,不然仅释放了指针所指的内存空间,指针所指的地址没有变,仍可进行一些操作。

 

C++中 new/delete 概念和用法总结

学过C++的程序员都知道,new/delete是其管理内存的主要方法。与C语言相比,C++支持面向对象技术,因此在内存管理方面有所区别。

在C++中,数据对象(基本类型和复合类型)的创建包括两个部分:一是给数据对象分配足够的内存,二是内存进行数据的初始化。而C中,只有第一个分配内存的作用。并且,不仅仅是类,其它基本类型,如int型等,也是如此。例如:

char* pc1 = new char;

char* pc2 = new char('A');

以上两条语句都能够给对应的指针分配内存,不同在于,第一条语句仅仅分配内存,而具体的内容是随机的;而第二条语句不仅分配内存,并且赋值为‘A’。相对应的,当不再需要这些内存时候,可以采用delete来释放内存。

C++中,关于new/delete相关的内容很多,初学者比较容易混淆概念。以下是笔者的一点总结,希望对那些还处于懵懵懂懂的程序员有帮助。

1. new/delete 关键字。C++和其它语言一样,也事先预留了一些单词作为系统使用。程序员是不能用这些单词来表示自己的数据的。如int , float, struct , class 等。当然new/delete也是。但是new/delete关键字仅仅是在词法上的定义,它只表明程序员不能重复定义它们,用来表达其它含义。

2. new/delete表达式。指的是new/delete与其它单词所组成的一条有具体词义的语句(运算符形式)。如 new char; 就是分配大小为一个byte的内存空间。在C++中,new/delete表达式在不同的情况下,有不同的实现途径。但是实现的功能都是一样的,就是处理内存相关操作。

3. operator new 和 operator delete 函数。这点很奇怪,在C++中,某些运算符号可以重载为函数来使用(尽管运算本身就是一种抽象的对数据处理的函数方式),因此operator new 和 operator delete是两个函数名称。但是这两种函数只是,分配内存而不初始化。这点与C语言的malloc和free比较类似。

4. 类成员函数new/delete。指的是类的成员函数,并且函数名是new和delete。这与3. 中的函数有点类似,只是3. 中的函数是标准空间中的函数,而类成员函数是类本身的成员函数。

接下来,是这4条之间的关系。1. 只是说明 new/delete两个单词程序员不能再定义使用,与具体的功能毫无关系。2.是一条与实际条件相关的,具有内存分配功能的表达式。 3.4是函数名,只是作用的空间大小不一样。简单说来就是: 单词, 表达式, 函数名 和 函数名。

当C++编译器碰到new/delete表达式的时候,它会去寻找相关的内存处理方式。 如果表达式的对象并没有定义自己的成员new函数,那么它就会去调用全局的new函数去分配内存;反之则调用成员函数的new函数去分配内存。接着根据参数的不同,去调用相应的初始化函数,也就是构造函数。也就是说new表达式会执行两个步骤:分配内存和初始化。 在分配内存的阶段,new表达式会有2种分配方式:全局的 operator new 或者是自定义的new成员函数。而初始化工作是调用构造函数来完成的。delete表达式功能和次序刚好相反,但是还是同意的机制。这就是new/delete相关几个概念的区别。一般地,不要去修改全局的operator new/ operator delete函数,但是根据需要,可以定义类的相应的成员函数来改变内存分配的方式。

关于new还单有一种功能(其实也是new的一种重载方式,但不进行分配内存操作,只是返回原来的内存地址),就是在指定的内存空间上创建一个对象,用法如下:

char buff[20];

CNone* pNone = new (buff) CNone();

假设CNone的大小不超过20个字节,那么就在buff开头的内存上,初始化一个对象。接着就可以通过pNone来进行操作。释放的方法如下:

pNone->~CNone();

那么类pNone对象就会被释放,但是内存buff并没有释放,依旧存在。

重载new/delete的原则是:尽量不要重载(很矛盾啊),除非完全清楚具体的分配情况。如果要重载,那么要实行配对法则。就是有new的重载,必须有其对应的delete重载,尽管有时候delete并不会进行内存的释放。

常见的重载函数形式有(参考<new>):

void* operator new (size_t size) throw(std::bad_alloc);

void operator delete (void* addr) throw();

void* operator new[] (size_t size) throw(std::bad_alloc);

void operator delete[] (void* addr) throw();

void* operator new (size_t size, nothrow_t &n) throw();

void operator delete (void* addr, nothrow_t &n) throw();

void* operator new (size_t size, void* p) throw() { return p;}

void operator delete (void* addr, void* p) throw() { }

除了最后一组外,其它组的内存分配就根据实际情况来实现。注意,对于size数值为0的情况,要在内部实现为1。这是因为C++标准要求空对象也要有实际的意义。

但是重载模式并不限于以上几组,原则上重载的new/delete组对有无数对,但是和实际相关的就只有那么几组而已。要注意的是,所有new/delete成对出现,但并不是代表用带参数的new创建的对象,在销毁的时候同样使用相同参数的delete去销毁,实际上是用标准的delete和delete[]去销毁的。对应的delete是在相应的对象创建失败时候,才调用的;并且不能是分配内存的时候,只能是在构造函数中出现异常时候才可以。这是系统自动实现的。并且按照从作用域的小到大进行搜索,找到一个捕获这个异常处理之后结束,否则就可能造成内存泄漏。

转自:http://blog.csdn.net/hsujouchen/archive/2009/08/17/4456519.aspx

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值