关于 Tmemorystream 动态内存分配(25分)

  • 主题发起人 jimi lee
  • 开始时间
J

jimi lee

Unregistered / Unconfirmed
GUEST, unregistred user!
REALLOC 分配的内存是否连续?

如何建立一个内存连续的MEMORYSTREAM?

 
T

tqz

Unregistered / Unconfirmed
GUEST, unregistred user!
MemoryStream本身就是内存连续的,不然怎么可以通过TMemoryStream.Memory
访问Stream所有的内容?
 
B

BiJ

Unregistered / Unconfirmed
GUEST, unregistred user!
我想realloc大概是reallocmem吧。
具体用法情趣看帮助。
MemoryStream应当就是内存连续的。
建立很简单:
var mem:TMemoryStream;
...
mem:=TMemoryStream.Create;
...
 
J

jimi lee

Unregistered / Unconfirmed
GUEST, unregistred user!

是指物理的内存地址是否连续。
 
R

redforks

Unregistered / Unconfirmed
GUEST, unregistred user!
物理的内存地址是不可能保证连续的,由于虚拟内存的存在,都不能保证内存在磁盘上还是物理内存里。
物理内存对程序没有太多的实际意义吧。
 

李颖

Unregistered / Unconfirmed
GUEST, unregistred user!
看了TMemoryStream源代码
如下:
procedure TMemoryStream.SetSize(NewSize: Longint);
var
OldPosition: Longint;
begin
OldPosition := FPosition;
SetCapacity(NewSize);
FSize := NewSize;
if OldPosition > NewSize then Seek(0, soFromEnd);
end;
其中SetCapacity分配新的容量,如下:
procedure TMemoryStream.SetCapacity(NewCapacity: Longint);
begin
SetPointer(Realloc(NewCapacity), FSize);
FCapacity := NewCapacity;
end;
其中SetPointer设置FMemory指针和FSize大小,
关键的Realloc方法如下:
function TMemoryStream.Realloc(var NewCapacity: Longint): Pointer;
begin
if NewCapacity > 0 then
NewCapacity := (NewCapacity + (MemoryDelta - 1)) and not (MemoryDelta - 1);
Result := Memory;
if NewCapacity <> FCapacity then
begin
if NewCapacity = 0 then
begin
GlobalFreePtr(Memory);
Result := nil;
end else
begin
if Capacity = 0 then
Result := GlobalAllocPtr(HeapAllocFlags, NewCapacity)
else
Result := GlobalReallocPtr(Memory, NewCapacity, HeapAllocFlags);
if Result = nil then raise EStreamError.Create(SMemoryStreamError);
end;
end;
end;
其中关键代码为:
//原来没有分配内存
if Capacity = 0 then
//新分配
Result := GlobalAllocPtr(HeapAllocFlags, NewCapacity)
else
//重新分配
Result := GlobalReallocPtr(Memory, NewCapacity, HeapAllocFlags);
这两个函数定义如下:
function GlobalAllocPtr(Flags: Integer
Bytes: Longint): Pointer;
{$EXTERNALSYM GlobalAllocPtr}
function GlobalReAllocPtr(P: Pointer
Bytes: Longint
Flags: Integer): Pointer;
{$EXTERNALSYM GlobalReAllocPtr}
是Win32 API,但在Win32 Help中没有找到相关的说明。
 
H

huizhang

Unregistered / Unconfirmed
GUEST, unregistred user!
DELPHI的内存分配都是通过MemortManager得到的,也就是说通过Windows内存管理得到
的。在你使用的时候感觉上是连续的,但物理上就不一定了,可能一部分是物理内存,一部
分是虚拟内存。虚拟内存同一页是连续的,跨页就不一定了。
 
J

jimi lee

Unregistered / Unconfirmed
GUEST, unregistred user!

如果MEMORYSTREAM 不能得到连续物理内存,可否先指定
一块区域(物理的),再去读取?(要弄一个DMA的采样程序,所以必须连续
物理内存。)各位大侠请指教。
 
J

jimi lee

Unregistered / Unconfirmed
GUEST, unregistred user!
是否必须VXD来实现物理内存读写?
 
M

menxin

Unregistered / Unconfirmed
GUEST, unregistred user!
请继续讨论或结束此问题。
 
J

jimi lee

Unregistered / Unconfirmed
GUEST, unregistred user!
多人接受答案了。
 
顶部