Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 11-07-2014
Avatar de Manuel
Manuel Manuel is offline
Miembro
 
Registrado: may 2003
Ubicación: San Pedro de la Paz/Chile
Posts: 324
Poder: 22
Manuel Va por buen camino
redimensionar varias veces un array

Hola amigos del club, por favor si me pueden ayudar con este problema que se presento, tengo lo siguiente, un array dinámico el cual lo dimensiono de la siguiente manera:

Código Delphi [-]
procedure calcular;
var
   Numeros: array of double;
   largo, i: integer;
begin
    i:=i;
    while i < 6 do
       begin
            SetLength(Numeros,i); 
            carga_datos(numeros);
            inc(i);
       end;
end;


Delphi 7 me acusa error de violación de memoria cuando al hacer por segunda vez el

Código Delphi [-]
SetLength(Numeros,i);

en el array numeros, como se puede hacer para redimensionar varias veces sin que se produzca el error?
__________________
Manuel Muñoz L. Trabajando con delphi 7.0 , migrando sistema a Delphi XE8, matando BDE y pasando FIREDAC.
Responder Con Cita
  #2  
Antiguo 11-07-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola Manuel.

Dos detalles, la inicialización de la variable de control y la forma que aumentas el tamaño del arreglo dinámico.
Código Delphi [-]
procedure calcular;
var
  Numeros: array of double;
  i: integer;
begin
  // i:=i; ( mal, el valor de 'i' no está definido )
  i:= 0;
  while i < 6 do
  begin
    // Tamaño anterior del arreglo dinámico, incrementado en uno
    SetLength(Numeros, Length(Numeros) + 1);
    carga_datos(Numeros);
    Inc(i);
  end;
end;
Aunque es mas simple:
Código Delphi [-]
procedure Calcular;
var
  Numeros: array of Double;
  i: Integer;
begin
  for i:= 0 to 5 do
  begin
    SetLength(Numeros, Length(Numeros)+1);
    carga_datos(Numeros);
  end;
end;
O como en estos casos, que sabemos de antemano que serán 6 elementos, mas simple todavía:
Código Delphi [-]
procedure Calcular;
var
  Numeros: array of Double;
  i: Integer;
begin
  SetLength(Numeros, 5);
  for i:= Low(Numeros) to High(Numeros) do  // o: for i:= 0 to 5 do ...
    carga_datos(Numeros);
end;

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #3  
Antiguo 11-07-2014
Avatar de Manuel
Manuel Manuel is offline
Miembro
 
Registrado: may 2003
Ubicación: San Pedro de la Paz/Chile
Posts: 324
Poder: 22
Manuel Va por buen camino
Gracias daniel, en todo caso es un ejemplo que puse solamente, el real es mucho mas complejo, la idea central que la función SetLength no deja ridemensionar varias veces el mismo array con diferentes posiciones por ejemplo:


Código Delphi [-]
SetLength(Numeros,10); 
..
//otras intrucciones
..
..


SetLength(Numeros,20); /// Acá se produce el error de violación de posición de memoria.

Una vez gracias Daniel.
__________________
Manuel Muñoz L. Trabajando con delphi 7.0 , migrando sistema a Delphi XE8, matando BDE y pasando FIREDAC.
Responder Con Cita
  #4  
Antiguo 11-07-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola Manuel.

Si no te entiendo mal es lógico, por que la segunda asignación del arreglo anula la primera. En tu ejemplo la cantidad de elementos no termina siendo 30 sino 20 ya que la última sentencia fija el tamaño del arreglo en esa cifra.

Tal vez con estos ejemplos pueda explicar mejor a que me refiero:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
  v: array of Integer;
  i: Integer;
begin
  // agregar 5 enteros
  for i:= 0 to 4 do
  begin
    SetLength(v, Length(v)+1);
    v[Length(v)-1]:= i;  
  end;

  // agregar diez enteros mas
  for i:= 500 to 509 do
  begin
    SetLength(v, Length(v)+1);
    v[High(v)]:= i;  // igual que: v[Length(v)-1]
  end;

  // mostrar
  for i:= Low(v) to High(v) do
    ListBox1.Items.Add(IntToStr(v[i]))
end;


Código Delphi [-]
procedure TForm1.Button2Click(Sender: TObject);
var
  v: array of Integer;
  i: Integer;
begin
  // agregar 5 enteros
  SetLength(v, 5);
  for i:= 0 to 5 do v[i]:= i;

  // agregar 10 mas
  SetLength(v, Length(v)+10);
  for i:= 0 to 9 do v[5+i]:= 500+i;

  // mostrar
  for i:= Low(v) to High(v) do
    ListBox1.Items.Add(IntToStr(v[i]));
end;

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Última edición por ecfisa fecha: 11-07-2014 a las 15:39:09. Razón: agregar ejemplo
Responder Con Cita
  #5  
Antiguo 11-07-2014
Avatar de Manuel
Manuel Manuel is offline
Miembro
 
Registrado: may 2003
Ubicación: San Pedro de la Paz/Chile
Posts: 324
Poder: 22
Manuel Va por buen camino
Gracias Daniel nuevamente, me he dado cuenta que cuando aumento la cantidad de elementos no hay problemas , pero si cuando se redimensiona a menos elementos se produce el error.
__________________
Manuel Muñoz L. Trabajando con delphi 7.0 , migrando sistema a Delphi XE8, matando BDE y pasando FIREDAC.
Responder Con Cita
  #6  
Antiguo 11-07-2014
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
Manuel,

Cita:
Empezado por Manuel
...¿como se puede hacer para redimensionar varias veces?...me he dado cuenta que cuando aumento la cantidad de elementos no hay problemas , pero si cuando se redimensiona a menos elementos se produce el error...


Revisa este código:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
   A1 : Array of Integer;
   i : Integer;
   Msg : String;

begin

   // Muestra Longitud de A1 la cual esta en Cero dado que no ha sido Redimensionado
   ShowMessage('Longitud de A1 = ' + IntToStr(Length(A1)));

   // Redimensiona a 10, Carga 10 Elementos y Muestra el Primer y Último Elemento de A1
   SetLength(A1,10);
   ShowMessage('Longitud de A1 = ' + IntToStr(Length(A1)));
   for i := Low(A1) to High(A1) do
      A1[i] := i+1;
   Msg := 'Primer y Último Elemento de A1 = ' + IntToStr(A1[Low(A1)]) + ',' + IntToStr(A1[High(A1)]);
   ShowMessage(Msg);

   // Redimensiona a 20, Carga 20 Elementos y Muestra el Primer y Último Elemento de A1
   SetLength(A1,20);
   ShowMessage('Longitud de A1 = ' + IntToStr(Length(A1)));
   for i := Low(A1) to High(A1) do
      A1[i] := i+1;
   Msg := 'Primer y Último Elemento de A1 = ' + IntToStr(A1[Low(A1)]) + ',' + IntToStr(A1[High(A1)]);
   ShowMessage(Msg);

   // Redimensiona a 30, Carga 30 Elementos y Muestra el Primer y Último Elemento de A1
   SetLength(A1,30);
   ShowMessage('Longitud de A1 = ' + IntToStr(Length(A1)));
   for i := Low(A1) to High(A1) do
      A1[i] := i+1;
   Msg := 'Primer y Último Elemento de A1 = ' + IntToStr(A1[Low(A1)]) + ',' + IntToStr(A1[High(A1)]);
   ShowMessage(Msg);

   // Redimensiona a 20, Carga 20 Elementos y Muestra el Primer y Último Elemento de A1
   SetLength(A1,20);
   ShowMessage('Longitud de A1 = ' + IntToStr(Length(A1)));
   for i := Low(A1) to High(A1) do
      A1[i] := i+1;
   Msg := 'Primer y Último Elemento de A1 = ' + IntToStr(A1[Low(A1)]) + ',' + IntToStr(A1[High(A1)]);
   ShowMessage(Msg);

   // Redimensiona a 10, Carga 10 Elementos y Muestra el Primer y Último Elemento de A1
   SetLength(A1,10);
   ShowMessage('Longitud de A1 = ' + IntToStr(Length(A1)));
   for i := Low(A1) to High(A1) do
      A1[i] := i+1;
   Msg := 'Primer y Último Elemento de A1 = ' + IntToStr(A1[Low(A1)]) + ',' + IntToStr(A1[High(A1)]);
   ShowMessage(Msg);

end;
El código anterior en Delphi 7 bajo Windows 7 Professional x32, redimensiona un arreglo de enteros en forma creciente y decreciente y efectúa operaciones sobre sus elementos.

Revisa esta información:
Espero sea útil

Nelson.

Última edición por nlsgarcia fecha: 11-07-2014 a las 20:33:20.
Responder Con Cita
  #7  
Antiguo 11-07-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola Manuel.

Hola Manuel
Cita:
Empezado por Manuel Ver Mensaje
..., pero si cuando se redimensiona a menos elementos se produce el error.
Te pongo un ejemplo que inicializa, aumenta y por último disminuye el tamaño de un arreglo dinámico:
Código Delphi [-]
type
  TDynArray = array of Integer;

procedure TForm1.Button1Click(Sender: TObject);

  procedure Mostrar(v: TDynArray);
  var
    i: Integer;
  begin
    for i:= Low(v) to High(v) do Memo1.Lines.Add(Format('%d',[i]));
    Memo1.Lines.Add(Format('  Elementos: %d',[Length(v)]));
    Memo1.Lines.Add('--------------------');
  end;

var
  da: TDynArray;
  i: Integer;
begin
  Memo1.Lines.Clear;
  Memo1.ScrollBars:= ssVertical;
  // Inicializar en 4 elementos
  SetLength(da, 4);
  for i:= 0 to 3 do da[i]:= i;
  Mostrar(da);

  // Aumentar en 4 elementos
  SetLength(da, Length(da) + 4);
  for i:= 0 to 3 do da[High(da)]:= High(da)+1;
  Mostrar(da);

  // Reducir a dos elementos
  SetLength(da, 2);
  Mostrar(da);

  // Desasignar memoria asociada 
  Finalize(da);
end;
El resultado:
Código:
0
1
2
3
  Elementos: 4
--------------------
0
1
2
3
4
5
6
7
  Elementos: 8
--------------------
0
1
  Elementos: 2
--------------------
Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Última edición por ecfisa fecha: 11-07-2014 a las 22:10:27.
Responder Con Cita
  #8  
Antiguo 11-07-2014
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Cita:
Empezado por Manuel Ver Mensaje
Delphi 7 me acusa error de violación de memoria cuando al hacer por segunda vez el

Código Delphi [-]
SetLength(Numeros,i);
Cuando te ocurran estas cosas, busca en google. Con "Acces violation SetLength" encontre varios links con posibles causas.

Ademas, para poder determinar que pasa con un error, el que sea, debes volverlo reproducible. No basta con simplemente mostrar codigo, debes mostrar el conjunto de pasos EXACTOS que genera el error, de lo contrario uno puede quedarse una eternidad adivinando estos casos.
__________________
El malabarista.
Responder Con Cita
  #9  
Antiguo 12-07-2014
Avatar de Manuel
Manuel Manuel is offline
Miembro
 
Registrado: may 2003
Ubicación: San Pedro de la Paz/Chile
Posts: 324
Poder: 22
Manuel Va por buen camino
Mil Gracias Daniel por tu ayuda, solucionado el problema después de cada SetLength(arreglo), coloque un Finalize(arreglo) y error se eliminó. Gracias una vez más.
__________________
Manuel Muñoz L. Trabajando con delphi 7.0 , migrando sistema a Delphi XE8, matando BDE y pasando FIREDAC.
Responder Con Cita
  #10  
Antiguo 12-07-2014
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
Manuel,

Cita:
Empezado por Manuel
...después de cada SetLength(arreglo), coloque un Finalize(arreglo)...


Nelson.
Responder Con Cita
  #11  
Antiguo 12-07-2014
Avatar de Manuel
Manuel Manuel is offline
Miembro
 
Registrado: may 2003
Ubicación: San Pedro de la Paz/Chile
Posts: 324
Poder: 22
Manuel Va por buen camino
Que cosa no entiendes?
__________________
Manuel Muñoz L. Trabajando con delphi 7.0 , migrando sistema a Delphi XE8, matando BDE y pasando FIREDAC.
Responder Con Cita
  #12  
Antiguo 12-07-2014
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
Manuel,

Cita:
Empezado por Manuel
...¿Que cosa no entiendes?...


Sería conveniente que publicaras el código en cuestión, en general no es necesario colocar un Finalize después de cada SetLength de un Arreglo Dinámico, como se puede ver en los códigos de los Msg #6 y Msg #7.

Cita:
Empezado por mamcx
...para poder determinar que pasa con un error, el que sea, debes volverlo reproducible. No basta con simplemente mostrar código, debes mostrar el conjunto de pasos EXACTOS que genera el error...


Nelson.
Responder Con Cita
  #13  
Antiguo 14-07-2014
Avatar de Manuel
Manuel Manuel is offline
Miembro
 
Registrado: may 2003
Ubicación: San Pedro de la Paz/Chile
Posts: 324
Poder: 22
Manuel Va por buen camino
Cita:
Empezado por nlsgarcia Ver Mensaje
Manuel,




Sería conveniente que publicaras el código en cuestión, en general no es necesario colocar un Finalize después de cada SetLength de un Arreglo Dinámico, como se puede ver en los códigos de los Msg #6 y Msg #7.




Nelson.
Nelson, mi sistema tenía bucle que redimensiona una y otra ves el mismo arreglo dinámico , el proble se presentaba cuando la redimensión era de menos elementos con respecto al último, al colocar Finalize se solucionó el problema.
__________________
Manuel Muñoz L. Trabajando con delphi 7.0 , migrando sistema a Delphi XE8, matando BDE y pasando FIREDAC.
Responder Con Cita
  #14  
Antiguo 14-07-2014
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
Manuel,

Cita:
Empezado por Manuel
...mi sistema tenía bucle que redimensiona una y otra ves el mismo arreglo dinámico...


Revisa este código:
Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Math;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
   A1 : Array of Integer;
   i,j : Integer;
   Delta : Integer;
   Msg : String;

begin

   Randomize;

   for i := 1 to 1000 do
   begin
      Delta := RandomRange(1,100);
      SetLength(A1,Delta);
      for j := Low(A1) to High(A1) do
         A1[j] := Random(500);
   end;

   ShowMessage('Longitud de A1 = ' + IntToStr(Length(A1)));
   Msg := 'Primer y Último Elemento de A1 = ' + IntToStr(A1[Low(A1)]) + ',' + IntToStr(A1[High(A1)]);
   ShowMessage(Msg);

end;

end.
El código anterior en Delphi 7 bajo Windows 7 Professional x32, redimensiona aleatoriamente en un loop un arreglo de enteros y efectúa operaciones sobre sus elementos.

Suerte en tu proyecto

Nelson.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Mi busca si lo hace varias veces Paulao Varios 0 05-07-2011 17:15:43
llamar varias veces un formulario Lizette Varios 3 05-11-2008 16:28:10
Imprimir un registro varias veces Vlady Impresión 1 29-08-2008 08:04:14
error al ejecutar un reporte varias veces mar65 Conexión con bases de datos 3 26-01-2005 13:01:28
Imprimir algo varias veces. aoiTo Impresión 0 20-07-2004 19:12:49


La franja horaria es GMT +2. Ahora son las 04:32:06.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi