我们知道 内存分配方式有三种:
为了更好的理解C程序内存分配方式及相关的生命周期,下面我们讨论一人例子:
#include "stdio.h"
#include "string.h"
class A
{
friend class T;
public:
void Add(char *sz)
{
m_szA = sz;
}
void print()
{
printf("%s/n", m_szA);
}
protected:
char *m_szA;
};
class T
{
public:
T()
{
strcpy(m_szT, "this is T string");
}
void AddforA(A &a)
{
static char staticstr[] = "this is static string";
a.Add(staticstr);
}
protected:
char m_szT[32];
};
void main()
{
T *pT = new T;
A a;
pT->AddforA(a);
delete pT;
a.print();
getchar();
}
上面程序定义了A类它有一个字符串指针变量,注意是指针,不随构造分配空间;可以调用Add方法为
它的符串指针赋值。print是它的打印函数。
另外定义了T类,它是A的友元类,T有一个字符串变量,注意是数组型,随构造分配空间并且构造为
this is T string字符串,AddforA是在T中为A的指针变量m_szA赋值。
在主程序中首先创建了T的指针对象pT并申请好内堆内存空间,另外声明一A的变量a,a是函数的局部变量,
它的生存周期是到主函数退出为止,接下去调用pT的addforA方法,并立刻释放pT资源,当打印a时发现成功
输出了this static string,可以证明它并没有随pT的释放而不复存在,因为static变量符合1的分配原则,它的生
命周期至程序退出为止。
假若将AddforA改为
void AddforA(A &a)
{
char temp[] = "this is temp string";
a.Add(temp);
}会怎样呢?
你将发现不管是a.paint在pT释放之前打印还是之后打印,结果都是乱码。这是因为temp是函数局部变量,生命
周期随函数执开始至执行结束。
假若将AddforA改为
void AddforA(A &a)
{
a.Add(m_szT);
}会怎样呢?
结果是如果a.print在delete pT之前调用会成功打印 this is T string,反之输出乱码。这是因为程序主动结束了m_szT所指向对象的生命。
假若将AddforA改为
void AddforA(A &a)
{
a.Add(“this is const string");
}会怎样呢?
我们发现可以成功打印this is const string。这是因为常量也是放在静态存储区的,它的生命周期与static变量一致。
以上仅为个人一点学习心得。欢迎交流讨论。
(1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
(2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。为了更好的理解C程序内存分配方式及相关的生命周期,下面我们讨论一人例子:
#include "stdio.h"
#include "string.h"
class A
{
friend class T;
public:
void Add(char *sz)
{
m_szA = sz;
}
void print()
{
printf("%s/n", m_szA);
}
protected:
char *m_szA;
};
class T
{
public:
T()
{
strcpy(m_szT, "this is T string");
}
void AddforA(A &a)
{
static char staticstr[] = "this is static string";
a.Add(staticstr);
}
protected:
char m_szT[32];
};
void main()
{
T *pT = new T;
A a;
pT->AddforA(a);
delete pT;
a.print();
getchar();
}
上面程序定义了A类它有一个字符串指针变量,注意是指针,不随构造分配空间;可以调用Add方法为
它的符串指针赋值。print是它的打印函数。
另外定义了T类,它是A的友元类,T有一个字符串变量,注意是数组型,随构造分配空间并且构造为
this is T string字符串,AddforA是在T中为A的指针变量m_szA赋值。
在主程序中首先创建了T的指针对象pT并申请好内堆内存空间,另外声明一A的变量a,a是函数的局部变量,
它的生存周期是到主函数退出为止,接下去调用pT的addforA方法,并立刻释放pT资源,当打印a时发现成功
输出了this static string,可以证明它并没有随pT的释放而不复存在,因为static变量符合1的分配原则,它的生
命周期至程序退出为止。
假若将AddforA改为
void AddforA(A &a)
{
char temp[] = "this is temp string";
a.Add(temp);
}会怎样呢?
你将发现不管是a.paint在pT释放之前打印还是之后打印,结果都是乱码。这是因为temp是函数局部变量,生命
周期随函数执开始至执行结束。
假若将AddforA改为
void AddforA(A &a)
{
a.Add(m_szT);
}会怎样呢?
结果是如果a.print在delete pT之前调用会成功打印 this is T string,反之输出乱码。这是因为程序主动结束了m_szT所指向对象的生命。
假若将AddforA改为
void AddforA(A &a)
{
a.Add(“this is const string");
}会怎样呢?
我们发现可以成功打印this is const string。这是因为常量也是放在静态存储区的,它的生命周期与static变量一致。
以上仅为个人一点学习心得。欢迎交流讨论。
本文通过实例详细解析了C++中的三种内存分配方式:静态存储区分配、栈上创建及堆上分配。并通过代码示例展示了不同类型的内存分配对变量生命周期的影响。

4553

被折叠的 条评论
为什么被折叠?



