C语言内存分配详解4
{
char *p = (char *)malloc(sizeof(char) * num);
return p;
}
void Test3(void)
{
char *str = NULL;
str = GetMemory3(100);
strcpy(str, "hello");
cout<< str << endl;
free(str);
}
示例4.3 用函数返回值来传递动态内存
用函数返回值来传递动态内存这种方法虽然好用,但是常常有人把return语句用错了。这
里强调不要用return语句返回指向"栈内存"的指针,因为该内存在函数结束时自动消亡,见
示例4.4。
char *GetString(void)
{
char p[] = "hello world";
return p; // 编译器将提出警告
}
void Test4(void)
{
char *str = NULL;
str = GetString(); // str 的内容是垃圾
cout<< str << endl;
}
示例4.4 return语句返回指向"栈内存"的指针
用调试器逐步跟踪Test4,发现执行str = GetString语句后str不再是NULL指针,但是
str的内容不是"hello world"而是垃圾。
如果把示例4.4改写成示例4.5,会怎么样?
char *GetString2(void)
{
char *p = "hello world";
return p;
}
void Test5(void)
{
char *str = NULL;
str = GetString2();
cout<< str << endl;
}
示例4.5 return语句返回常量字符串
函数Test5运行虽然不会出错,但是函数GetString2的设计概念却是错误的。因为
GetString2内的"hello world"是常量字符串,位于静态存储区,它在程序生命期内恒定不变。
无论什么时候调用GetString2,它返回的始终是同一个"只读"的内存块。
5、杜绝"野指针"
"野指针"不是NULL指针,是指向"垃圾"内存的指针。人们一般不会错用NULL指针,因
为用if语句很容易判断。但是"野指针"是很危险的,if语句对它不起作用。 "野指针"的
成因主要有两种:
(1)指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的缺省
值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为
NULL,要么让它指向合法的内存。例如
char *p = NULL;
char *str = (char *) malloc(100);
(2)指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。
(3)指针操作超越了变量的作用范围。这种情况让人防不胜防,示例程序如下:
class A
{
public:
void Func(void){ cout << "Func of class A" << endl; }
};
void Test(void)
{
A *p;
{
A a;
p = &a; // 注意 a 的生命期
}
p->Func(); // p是"野指针"
}
函数Test在执行语句p->Func()时,对象a已经消失,而p是指向a的,所以p就成了"野
指针"。但奇怪的是我运行这个程序时居然没有出错,这可能与编译器有关。
6、有了malloc/free为什么还要new/delete?
malloc与free是C /C语言的标准库函数,new/delete是C 的运算符。它们都可用于申请
动态内存和释放内存。
对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建
的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数
而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于
malloc/free。
因此C 语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清
理与释放内存工作的运算符delete。注意new/delete不是库函数。我们先看一看malloc/free
和new/delete如何实现对象的动态内存管理,见示例6。
class Obj
{
public :
Obj(void){ cout << "Initialization" << endl; }
声明: 除非转自他站(如有侵权,请联系处理)外,本文采用 BY-NC-SA 协议进行授权 | 嗅谱网
转载请注明:转自《C语言内存分配详解4》
本文地址:http://www.xiupu.net/archives-648.html
关注公众号:
微信赞赏
支付宝赞赏