一个指针有结束的地址吗?(100分)

  • 主题发起人 主题发起人 wddelphi
  • 开始时间 开始时间
W

wddelphi

Unregistered / Unconfirmed
GUEST, unregistred user!
老鸟们可别骂我,我已经在全文检索中检索过了,好像没有答案,所以来提问了。

问题一:
一个指针有结束的地址吗?
比如,一个对象(指针),TForm1,它的地址是@Form1,但是否应该有个结束的地址呢?
比如<EOF>?我想用sizeof取对象的大小,结果都是4(我想应该是integer(指针)的
size吧!),没有结束标志,我怎么计算这个对象占用的内存是多少?像自己做链表,
总有个标志可以识别其为最后的节点,那对象或其它指针怎么识别的?

问题二:
知道一个对象(指针)的地址,比如,@Form1,我该怎样一个字节一个字节地读下去,
把指针转成integer,再加上要移动的长度,再读取,是这样吗?

还有,一个进程也有它的运行空间,不能访问到其它进程的内存中去,那它也
应该有个标志结束的地址,不然我在程序中顺着某个变量的地址一直往下移,不就能访
问到其它进程中去了吗?

请各位高手帮忙解答,如果嫌分少~555,我还有100块私房钱也贴出来~
 
1、没有结束标志,用 InstanceSize 得到大小。但是一般vcl对象它里面还包含指针指向别处,
别处的内存不包含在InstanceSize中
例如:Self.InstanceSize
 
对象并不一定是存贮在连续内存空间内的,所以取得的大小可能与实际的不符。
 
2、Form1就是指针了,@Form1就不对了,(你要强制 Pointer(Form1) 使用)
另外你不能用 读取 Form1开始的 Form1.InstanceSize 字节来保存对象,上面说了
里面它还有指向别处的指针
 
还有:
操作系统并不是把这个进程分配内存 1-200 另外进程分配201-400这样
而是操作系统保存一个内存映射表,每个进程都一个内存映射,切换任务的时候也要切换内存映射
我们的进程是不能直接访问物理内存的,我们访问的内存地址其实是逻辑的
386以上的cpu,根据内存映射表,从逻辑的地址(线性地址)映射到物理地址
所以,不同进程访问 0x400000地址,访问的物理内存不同
而指针变量用错了,访问的地址不在内存映射表中,就出现地址访问冲突的错误了
 
1:要看是什么指针了
如果是数组等就是结束地址
类指针等是没有的
2:Form1是指针,@Form1是指针的地址,由于一个类包括许多成员等,所以不能对指针加
地址那样操作,在类里面,编译器都是隐藏的表,类指针靠这个表来操作。
3:不会出现你说的情况,因为现在操作系统都是多任务,内存也是虚拟内存,每个进程的
内存都是分开的,指针移动也只能在本进程内移动,并且并进程的内存有一部分是操作
系统使用,只有一定的权限才能使用。在实模式下面一般可以通过指针移动访问别的内存
 
Pipi大虾讲的已经比较明白了,我觉得顶楼的这么问说明对指针还不是很明白,对Windows
的进程的一些基础的理论也不是很明白。(BTW:Pipi说的0x400000地址是默认的映像基)
 
9x下面exe文件默认基址是0x400000
2k下面是0x100000
 
对象的具体内容是不能通过指针访问的。
 
注:我说的 0x400000 只是举个例子,用来说明相同的地址在不同的进程是映射到不同的物理地址的
(虽然也有可能映射到同一个物理地址,比如相同的代码段,与操作系统的管理有关)
并不表示它是一定是个合法的地址
 
是啊,正如shenloqi所说,我一些基础的理论也不是很明白,
其实我是想通过一个对象的首地址,一个byte一个byte地读出它所有的内容,如果不知道它
的结束点,我怎么能确认恰好读完了这个对象的所有内容了呢?
我知道对象并不一定是存贮在连续内存空间内的,但应该怎样从一个对象的首地址去访问它
分散在内存中的各个部分呢?

谢谢各位高手对这个问题的关注!
 
1:要看是什么指针了
如果是数组等就是结束地址

我觉得不是这样的,所有的指针都是一个整型,它本身没有结尾的标志的。
但你可以用一个格式去读取它的结尾,比如STRING就是一个以NULL为结尾的指针。
所有的对象都是指针,当然包括FORM1
 
如果你真想知道指针所在的内存空间,也是有办法的,因为操作系统分配内存时都会记录
每块内存的大小,只是,你必须要找到内存分配表。以你目前的水平,无法做到。
BTW:你为什么要这么做?有什么用?
 
多谢SS2000的提醒,我是提问的,如果你能回答且愿意回答,就请回答问题吧!
 
我已经告诉你了要找到内存分配表,你自己找吧,难道要我告诉你,那我可以写篇专著了
 
一个对象的实例当然是存贮在连续内存空间内的,只是每个对象自己还不定的有一些指针成员,它指向了其他内存(我们不可知,只有写程序的人才知道,
在创建对象的时候也创建他们,删除的时候也删除他们),你只是保存实例本身的数据并没有用
 
比如 TForm1 里面有 Edit1 ,
edit1是个指针,一个4字节的指针,指向TEdit的实例
你保存TForm1的实例的内存,只是保存了Edit1的指针值,就这个意思
但是 Form1 这个实例的内容你是拷贝齐全了的
(当然Form1和Form1.Edit1不是连接的,但是一个对象实例它是连续的
比如,Form1开始的连续 TForm1.instanceSize 个字节就是Form1的实例数据)
 
多谢SS2000的回答,虽然我说我一些基础的理论也不是很明白,但是你说的那些,我也是
知道的,虽然你的回答没有什么用,可还是要谢谢你费心!

更要谢谢Pipi.对这个问题的一直关心,其实你说的就是我想做的,比如TTreeview有个
Data指针,它指向的可能是任一变量、结构或对象,我想做的就是得到这些数据,分析,
并存储它们,如果不知道它的结束点,我怎么能确认恰好读完了这个对象的所有内容了呢?
你说:“一个对象的实例当然是存贮在连续内存空间内的”,真是这样的吗?如果是,我
想那也好办,引用你的例子:
比如 TForm1 里面有 Edit1 ,edit1是个指针,一个4字节的指针,指向TEdit的实例,
(当然Form1和Form1.Edit1不是连接的,但是一个对象实例它是连续的
比如,Form1开始的连续 TForm1.instanceSize 个字节就是Form1的实例数据)。
那Edit1的内存空间应该也是连续的喽,那我根据指针Edit1去访问它那段连续的空间,应该
可以得到整个Edit1的内容了?
 
to Pipi.:
好像又有问题了,怎样判断一个属性是普通变量还是指针呢?
 
后退
顶部