在Wind32环境下运行的程序,其在内存中所占用的内存区域为00400000 -- 7FFFFFFF,即4M--2G的地址空间,那么我怎么知道在这区间,哪些区域是可写、可读的呢?对于char *pstr = "Hello World";如果pstr = 0x004318E8,那么为什么[0x004318E8]指定的内存区域就不可写了呢?内存的读写属性是通过什么来控制的?
还有怎样知道一个程序的堆/栈内存区域是多大?都从内存的什么地方开始?这是在PE的文件信息中规定的吗?还是在编译的时候确定?JerKii
不好意思,没多少分了!

解决方案 »

  1.   

    接上文:
    对于[0x004318E8]指定的内存区域,因为“Hello World”占用了一定的存储区域,那这段区域在什么时候被释放啊?好像是不能使用delete pstr;来释放该内存区域吧!如果不能释放的话,那不是像“char *p = "xxxxx"”这样的语句越多浪费的内存就越大吗?
    对于
    char *p = new char[10];可以更改p指向的内存区域,并通过delte p;来释放;
    char p[] = "xxx";由于是在栈上分配内存区域,其空间会被自动释放(应该说是会被在需要的时候被重新分配)
    char *p = "xxxx";p指向的内存区域就不可以更改,但是怎样来释放这块内存呢?
    这里我所指的指定的内存区域是否可写主要是指能否执行下面的指令:
    mov eax, 0xXXXXXXXX
    mov dword ptr[eax], 0x22JerKii
      

  2.   

    win32采用平坦内存模式,因此4M-2G内存空间中,只要页面存在,并且该页面没有设为只读属性,都是可读写的。换名话说,内存读写属性是由页面属性决定的。
    char *p = "xxxx";
    这里“xxxx”存放于程序只读数据区,它当然由PE文件规定,只能在程序结束后释放。
      

  3.   

    还有一点就是编译器怎么知道我的程序需要多大的堆空间、栈空间、甚至是内存空间啊?
    如果我的程序里有无限循环在创建对象(使用new操作符)并且不释放,那么编译器“预设”的堆空间岂不是会不够?这样会出现什么样的情况?对于一种极端的情况,如果一个程序需要超过2G的内存空间的话,该程序能运行吗?
      

  4.   

    char *pstr = "Hello World"这句话在C++中,应该是这样理解,首先定义一个const的串,然后申明一个指针,这个指针,当然这个指针指向这个静态地址。这样就容易理解了吧!
        还有怎样知道一个程序的堆/栈内存区域是多大?都从内存的什么地方开始?这是在PE的文件信息中规定的吗?还是在编译的时候确定?
        检查堆栈的内存区域,可以查看你的esp/寄存器的内容,在vc中编译的时候选择查看窗口中的寄存器窗口,或者使用alt+5就可以详细的知道栈的情况  
        对于一种极端的情况,如果一个程序需要超过2G的内存空间的话,该程序能运行吗?
        win32可以虚拟到4G的空间,虽然这些空间未必都是真实的,比如说很多时候是依靠换入换出页面来实现的,但是你放心2个G是完全没有问题的!
        那页面的读写属性又是谁决定的呢?
        页面的读写属性,当然是由编译器决定的,你没有写顶吧?呵呵!
        其实高级语言是不能实现那样底层的东西的设置的,一般来说win32中只有代码段和数据断的概念,而代码段是不能写操作的,但是数据段可以!
        还有什么问题吗?别忘了给分!^_^
      

  5.   

    在PE文件中,有若于区(Section),如只读数据区,代码区,未初始化数据区等。这些区决定了操作系统加载程序时如何来设置页面的属性。