2009-07-13 10 views
8

Tengo un problema tan básico en Delphi que no lo puedo resolver.¿Cómo copiar una matriz?

Mi Código:

Nota: Datar es local en los siguientes métodos, pero por lo general es una clase var.Just para el concepto es local.

class procedure TCelebrity.BeginRead(var input:Array of byte); 
var DataR:Array of byte; 
begin 
    VirtualFree(@DataRead,High(DataRead),MEM_RELEASE); 
    SetLength(DataR,Length(input)); 
    Move(input,DataR,Length(input)); 
end; 

Esto compila, pero después de Mover() se ejecuta Datar = nil.

Segundo intento:

class procedure TCelebrity.BeginRead(var input:Array of byte); 
var DataR:Array of byte; 
begin 
    VirtualFree(@DataRead,High(DataRead),MEM_RELEASE); 
    SetLength(DataR,Length(input)); 
    DataR := Copy(input,0,Length(input)); 
end; 

Esto no se compila en all.Error en la tercera línea (Datar: = Copiar (entrada ....) diciendo "tipos incompatibles"

Dónde está. ?! el problema todos ellos son de matriz de bytes

Respuesta

7

Por qué no utilizar para la

SetLength(DataR,Length(input)); 
for i:=Low(input) to High(input) do 
    DataR[i]:=input[i]; 

Por cierto: si quieres tienen matrices que pasan como parámetro, debe hacerlo como un tipo, por ejemplo:

type 
    TMyArray = array of byte; 

y utilizar TMyArray como tipo de parámetros.

Editar: Me han notificado un valor inferior. En mi publicación original fue para i: = 0, pero i: = Bajo (entrada) es más seguro y más puro.

+0

Tengo una pregunta. VirtualFree siempre devuelve falso, entonces, ¿cómo puedo liberar la memoria utilizada actualmente con DataR? Nota DataR no es local, sino var de clase en el código original. ¡Gracias de antemano por la respuesta! –

+0

No, no tienes matrices simples gratuitas. Tales matrices se liberan automáticamente (por ejemplo, cuando tu clase está siendo destruida). Nota: si tiene una matriz de referencias a objetos, debe liberar esos objetos manualmente, ya que Delphi solo liberará la matriz. – smok1

+0

También tenga en cuenta que SetLenght reasigna toda la matriz, así que evite el uso intensivo de este procedimiento. Cuando haces la matriz más larga con SetLength, el contenido actual permanece intacto, sin embargo, cuando lo haces más corto, parte del contenido se perderá. – smok1

2

Probar:

class procedure TCelebrity.BeginRead(var input:Array of byte); 
var DataR:Array of byte; 
begin 
    VirtualFree(@DataRead,High(DataRead),MEM_RELEASE); 
    SetLength(DataR,Length(input)); 
    Move(input[0],DataR,Length(input)); 
end; 
+0

Lo hice, no funciona. –

8

tratar este procedimiento Mover

type 
    TByteDynArray = array of Byte; 

function CopyData(const Input:array of Byte):TByteDynArray; 
begin 
    SetLength(Result, Length(Input)); 
    Move(input[0], Result[0], Length(Input)); 
end; 
+5

Una respuesta correcta. pero para que sea una * buena * respuesta, debe explicar * por qué * sus cambios son significativos. De lo contrario, es solo un hechizo mágico. –

+3

Corrígeme si me equivoco, pero podría valer la pena señalar que esto solo funciona como está escrito para 'array of Byte'. Si la matriz fuera diferente, digamos 'array of Integer', entonces necesitaría' Move (entrada [0], Result [0], Length (Input) * SizeOf (Integer)) '. Solo digo. –

+0

@Rob Kennedy: Move() en delphi es similar a memcpy()/memmove() en C – dns

1

no va a mover una sección de la memoria. Copia Count bytes. De este modo obtendrá dos matrices idénticas diferentes: Entrada y DataR.

procedure CopyData(const Input: Array of Byte); 
var 
    DataR: Array of Byte; 
begin 
    SetLength(DataR, Length(Input)); 
    Move(Input[0], DataR[0], SizeOf(Byte)*Length(Input)); 
end; 

P.s. con arrays estáticos puede usar SizeOf (Input) en lugar de SizeOf (Byte) * Length (Input). En lugar de Byte podría ser otro tipo de datos.

+0

¿por qué no usar SizeOf (Entrada [0]) en lugar de un tipo de datos codificado? –

Cuestiones relacionadas