我用MFC建一个Dialog,发现在OnInitDialog里(都是局部的):
1.用CButton bt; bt.Create(...); Button不会显示出来.内存东西变了.
2.用CButton* bt=new CButton;bt->Create(...); Button会显示出来.问题1.bt怎么不会出来,是不是就是bt是在 全局静态内存 中?是由系统给释放了吗?如果是由系统释放了,那么看第二题,不是,那么说明是什么
问题2.如果是,那么,看这里
void init()
{
char* szText="ddd";//这里"ddd"是分配在全局静态内存中的,且把地址给了szText;那么这个函数结束后为什么这个内存还有值呢,即原始"ddd"的那部分空间还存在刚才的值(而不是szText,这里是用Debug中的Memory窗口看的)?
}
问题3.如声明了char* szText;....那么用过后要我们自己释放.那么,声明了int* p=new int;*p=1;呢,这是不是还得我们自己释放呀(int型的太简单了,有点迷糊,不知道是不是要释放,这里这个int指针也是在动态内存区的吗?)?
1.用CButton bt; bt.Create(...); Button不会显示出来.内存东西变了.
2.用CButton* bt=new CButton;bt->Create(...); Button会显示出来.问题1.bt怎么不会出来,是不是就是bt是在 全局静态内存 中?是由系统给释放了吗?如果是由系统释放了,那么看第二题,不是,那么说明是什么
问题2.如果是,那么,看这里
void init()
{
char* szText="ddd";//这里"ddd"是分配在全局静态内存中的,且把地址给了szText;那么这个函数结束后为什么这个内存还有值呢,即原始"ddd"的那部分空间还存在刚才的值(而不是szText,这里是用Debug中的Memory窗口看的)?
}
问题3.如声明了char* szText;....那么用过后要我们自己释放.那么,声明了int* p=new int;*p=1;呢,这是不是还得我们自己释放呀(int型的太简单了,有点迷糊,不知道是不是要释放,这里这个int指针也是在动态内存区的吗?)?
2,这种方式也相当于你new了一块内存来存"ddd",所以你没delete里面的数据也还是存在的
3,这个还是一样,只要new了,就要去delete不管是什么类型,否则内存泄漏
2、"ddd"是常量,不是动态变量,是不能释放的。szText是指针变量,函数返回时释放的是这个变量,不是释放其指向的内存。
3、同2。
...
CButton bt;
bt.Create(...
...
}
是的,函数返回时变量 bt 的生命期就结束了,这个没错;但为什么建立的按钮也没有了呢?不知道为什么,有兴趣的朋友可以研究一下,
这有助于你更好的理解 C++ 对象 和 窗口对象。
1.如下:
#include "stdafx.h"
#include <string>
void add()
{
char *szChar1="www";
int nIndex=6;
}
int main(int argc, char* argv[])
{
add();
char *szChar2="yyy";
return 0;
}我做了测试,不一定正确,但结果如下(Debug,用Memory查看当前内存):
由add()进入,查到内存区的szChar1: 0x0042201c(查Memory,值是"www")
&nIndex: 0x0012ff20(查Memory,值是6)add()执行完毕,到 char *szChar2="yyy";
我同样根据刚才记录的那些变量地址
0x0042201c(值还是"www"),
0x0012ff20(值还是6)
问题4:这说明了什么呢?是没有释放吗(什么是释放呢,是要==NULL或其它的吗)?还是其它什么?是这样说的吗?那么我用下面的代码会错的,注释是我自己的理解char *szChar1="www";
delete []szChar1;//1.因为我没有new,这个"www"是在静态内存中的,是不能更改的,所以delete会出错,如果用下面的就没有错了char *szChar1=new char[3];
strcopy(szChar1,"ddd");
delete []szChar1;//2.这里没报错,因为它用的是自己申请的空间,自己delete没有问题不对的地方还请指出
#include <string>
class classNew
{
public:
classNew(){y=1;};
~classNew(){};
public:
int y;
};
void add()
{
classNew cN;//记录地址&cN(内存查看);
int nIndex=2;//记录地址&nIndex,也就是2的地址(内存查看);
}
int main(int argc, char* argv[])
{
add();
int test=1;//检&cN和&nIndex刚记录的地址数据是否更改(内存查看)
return 0;
}
结果,&cN的内存是在离开add函数体后,改变了,但&nIndex这个内存区还没有改变,为什么呢?
&cN地址变了那是类的析构函数析构的结果,&nIndex没有变因为它只是普通变量地址,没类似析构函数的操作,地址是不会改变的,但里面的值1肯定是没了
1.Debug就是在执行编译,即编译没有完成.
2.能Debug就说明已经编译完成了.1,2两种关系是哪 个呢,要是第一个,那么说对了,要是第二个.就有问题了
我是Debug了两边,先Debug到
int nIndex=2;//记录地址&nIndex,也就是2的地址(内存查看);
然后记住&nIndex人地址。然后,停止Debug,再第二次Debug,还用刚才的地址。在没有运行到
int nIndex=2;//记录地址&nIndex,也就是2的地址(内存查看);
的时候,看一下刚才的地址,没有,然后运行到
int nIndex=2;//记录地址&nIndex,也就是2的地址(内存查看);
发现变化了,这时候为了确认刚才的地址和现在的地址是一样的,我还是看了&nIndex,和刚才的一样
所以地址是没有错误,两次的一样。
char szChar1[] = "www";//局部变量,分配在栈上,离开作用域后,自动释放CButton bt; bt.Create(...); //局部变量,分配在栈上,离开作用域后,自动释放
char *szChar1=new char[3]; //new动态内存分配,分配在堆上,需要开发人员自己用delete手动释放
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放
4、文字常量区—常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码。