Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem Rychlá pomoc s programem (Delphi7)

Ahoj,
z časových důvodů potřebuji někoho, kdo mi pomůže s jednou mou aplikací v Delphi. Je to jednoduché demo předvádějící grafické transformace.
Problém asi s dědičností (Canvas-Bod-Primka...), kdy se mi pak některé prvky snaží uvolňovat 2x a celý program je nestabilní a neustále vyhazuje AV (při ukončení).
Nemůžu na to přijít proč a jak to navrhnout správně, tak chci zkusit druhé oči.

Potřebuji testovat vlastní kreslící algoritmy, to ale nemůžu, když mám špatně navržený základ. V delphi už dělám spíš příležitostně, tak mi to moc nejde.

Odměna dohodou, spěchá.

Předmět Autor Datum
Když nemůžeš najít proč se to uvolňuje dvakrát, tak jednoduchá finta (ale není to elegantní řešení,…
Rce 26.01.2016 00:37
Rce
Takto to mám, ale problém to neřeší. Podle mého jde o to, že na formu mám image, a pak mám vlastní t…
MilanC 26.01.2016 00:44
MilanC
To ne přepisovat destruktory je cesta do pekla. Máš nějaký binec v ownerech přidávaných objektů. Jes…
Rce 26.01.2016 00:48
Rce
Jo je to jeden form s image ale všechny mé vlastní třídy pak vytvářím dynamicky. Jinak používám jen…
MilanC 26.01.2016 00:52
MilanC
Určitě. Dělám s tím programy pro Linux úplně bááááječně, pro Widle taky. Jestli to přidáváš dynamick…
Rce 26.01.2016 01:02
Rce
Můžeš mi poslat zdroják na rce(zavináč)arkotechnik(tečka)cz a můžu se na to zkusit mrknout, mám ješt…
Rce 26.01.2016 01:04
Rce
No a co jsem se pokoušel to trasovat, tak při destroy BaseCanvas se Image uvolní, a pak při destroy…
Jan Fiala 26.01.2016 09:51
Jan Fiala
Urob to v C(prip. aj ++ ak chces) a nebudes mat taketo problemy.
MM.. 26.01.2016 09:21
MM..
To je rada jak cyp...::) Fungovat to musi v jakemkoliv jazyce, kdyz to bude napsane spravne...
MaSo 26.01.2016 09:36
MaSo
No ale evidentne to napsat spravne nevie. Delphi a podobne kde si predavas hore dole objekty vytvore…
MM.. 26.01.2016 09:41
MM..
V Delphi se taky nic nedela "samo". Není tam zadne automaticke uvolnovani, jako v C#, zadne garbage…
Jan Fiala 26.01.2016 09:47
Jan Fiala
Tak to budes, ale osefujes si to vsetko sam ptz si to musis vsetko urobit sam :) BTW. k tomu dotazu…
MM.. 26.01.2016 09:50
MM..
V Delphi si delas taky vse sam - vytvaris, rusis. Funguje to stejne jako C++. Neni to zadny semi lan…
Jan Fiala 26.01.2016 09:54
Jan Fiala
A rozlisujes aj medzi tym ze co je len pointer a co je skutocny objekt? ;) (IMHO to je to co moze z…
MM.. 26.01.2016 09:58
MM..
Tim, ze priradis objekt do jineho, tak predas ukazatel na objekt, ale pak pracujes primo s vlastnost…
Jan Fiala 26.01.2016 10:09
Jan Fiala
priklad: class Cosi { public: Neco neco; // staticke, vytvorenie aj delete mi osefuje konstruktor a…
MM.. 26.01.2016 10:03
MM..
Tohle funguje stejne a chova se to stejne. Co si takto dynamicky vytvoris, tak si to musis sam i zru…
Jan Fiala 26.01.2016 10:12
Jan Fiala
Ja si myslim ze je to matuce, minimalne to oznacovanie (prve je objekt, a vyssie pises ze to je furt…
MM.. 26.01.2016 10:17
MM..
To NEco1 je uz vytvorene automaticky? Ak ano tak co sa stane ked napise Neco1 = new integer ? a poto…
MM.. 26.01.2016 10:27
MM..
Pointery se normalne v objektu nepouzivaji, protoze neni duvod. To neco1 je staticke - treba metoda…
Jan Fiala 26.01.2016 10:46
Jan Fiala
Presne o tom pisem ze z toho tvojho zapisu neni jasne ci je v pamati cely objekt alebo ne. promennaO…
MM.. 26.01.2016 14:35
MM..
Oba zapisu jsou totozne a odkazuji se na objekt Form1.Imagex (je to jen forma pointeru). Nealokujes…
Jan Fiala 26.01.2016 14:49
Jan Fiala
V C si to mozes osefovat sam ze ci si skopirujes objekt, alebo len priradis pointer
MM.. 26.01.2016 16:05
MM..
Taky si muzu zkopirovat objekt, treba: mujobrazek.assign(form1.image); pak mam v promenne mujobrazek…
Jan Fiala 26.01.2016 20:38
Jan Fiala
Ale ten zapis je matuci.
MM.. 26.01.2016 23:51
MM..
Neco integer Neco := 1 kopirujes hodnotu Neco neviemco Neco := necoine zasa kopiruje pointer je v to…
MM.. 26.01.2016 23:53
MM..
Tak jsem ti něco poslal... poslední
Rce 27.01.2016 02:20
Rce

Když nemůžeš najít proč se to uvolňuje dvakrát, tak jednoduchá finta (ale není to elegantní řešení, leč funguje):

if Assigned (MujObjekt) then begn MujObjekt.Free (); MujObjekt := nil end;

nebo já používám na to proceduru:

procedure MyFreeAndNil (var AObject: TObject);
begin if Assigned (AObject) then begin AObject.Free (); AObject := nil end
end;

// pak voláme jen:
MyFreeAndNil (MujObjekt);

Pro přesnější radu bych musel program vidět. Nemusí (jak se mi zdá) jít o problém dědičnosti, ale zapouzdřenosti (to je rozdíl!) Kontejnerový objekt by měl sám uvolnit uvnitř přidané objekty, ale musí je znát, proto zadáváme do konstruktoru objekt majitele (obvykle parametr AOwner). Konstruktor pak zajistí, aby kontejnerový objekt (třeba formulář) sám uvolnil vnořené objekty (tlačítka, canvas, textová pole....).

Takto to mám, ale problém to neřeší.
Podle mého jde o to, že na formu mám image, a pak mám vlastní třídu BaseCanvas, která má privátní proměnnou Image (nastavuji konstruktorem).
No a co jsem se pokoušel to trasovat, tak při destroy BaseCanvas se Image uvolní, a pak při destroy formu se ho snaží zrušit znovu.
Snažil jsem se různě přepisovat destruktory (override bez inherited), ale bez výsledku. Možná je ale potíž úplně v něčem jiném... :(

Můžeš mi když tak, prosím, napsat kontakt na cizek.milan@seznam.cz, zdrojáky poskytnu.
Skype/Jabber také můj mail.

To ne přepisovat destruktory je cesta do pekla. Máš nějaký binec v ownerech přidávaných objektů. Jestli je přidáváš v IDE rovnou taháním myši na form, nestarej se o nic, form to uvolní sám v pohodě. Jestli to přidáváš dynamicky, tak musíš volat správné metody aby se to správně propojilo, teď to nemám delphi před sebou, abych ti to správně řekl (používám free Lazarus).

Můžeš mi poslat zdroják na rce(zavináč)arkotechnik(tečka)cz a můžu se na to zkusit mrknout, mám ještě někde Delphi 7. Jsem teď ale dost vytížen, tak neslibuju, jestli se k tomu rychle dostanu.

//edit: V podstatě podobného něco jsem dělal, program na editaci obrázků, kde jsem náhledy (TImage) dynamicky cpal do mřížky. Funguje to dobře, s uvolňováním nemám problémy.

No a co jsem se pokoušel to trasovat, tak při destroy BaseCanvas se Image uvolní, a pak při destroy formu se ho snaží zrušit znovu.

Ta tva trida urcite neuvolnuje predany Image automaticky, to musis uvolnovat nekde ty v destroy sveho objektu.
Formular je vlastnikem Image, takze bys mel nechat jeho uvolneni na formulari.

V Delphi se taky nic nedela "samo". Není tam zadne automaticke uvolnovani, jako v C#, zadne garbage collectory.
Je na tobe, abys to napsal v poradku.
V C++ si taky predavas ukazatele na objekty. Pokud si predas ukazatel, na jinem miste ten objekt uvolnis a budes se k nemu snazit pristupovat, dopadnes stejne - access violation.
TCanvas (platno) je jen objekt, ktery umoznuje vykreslovani. Pokud bys to delal v C++, budes neco takoveho potrebovat taky, pokud to budes chtit vizualizovat.

Tak to budes, ale osefujes si to vsetko sam ptz si to musis vsetko urobit sam :)

BTW. k tomu dotazu - ked mu canvas chce pristupovat na objekt ktory uvolnil predtym, tak nech hlada problem tam, a osefuje si pristup na objekt ked uz neexistuje nejakym if, alebo nech ten objekt vyhodi z canvasu prec.

Tim, ze priradis objekt do jineho, tak predas ukazatel na objekt, ale pak pracujes primo s vlastnostmi objektu.

V podate prace s objekty v Delphi (tecka) odpovida praci v C++ (pomlcka+sipka)
Delphi: myclass.DoSomething();
C++: myclass->DoSomething();
Kdyz takto nekde v C++ predas objekt do nejake metody jako parametr a uvnitr metody jej zrusis, tak jsi zrusil objekt. Stejne jako V Delphi.

Muzes pracovat i primo s obecnym pointerem, pak kdyz se chces dostat na vlastnosti, tak si musis ponter pretypovat na ten objekt. Tohle se moc nepouziva, protoze neni duvod a stezuje to citelnost kodu.

priklad:
class Cosi
{
public:
Neco neco; // staticke, vytvorenie aj delete mi osefuje konstruktor a destruktor triedy Cosi.
Neco *neco = NULL; // pointer na nejake moje dynamicky vytvarane neco, a nikto sa mi do toho nesere. Sam si musim osetrovat pristpy a nepristupovat ak to je NULL, a nastavovat na NULL ak objekt deletnem.
}

To NEco1 je uz vytvorene automaticky? Ak ano tak co sa stane ked napise
Neco1 = new integer
?
a potom delete Neco1
a destruktor potom sa snazi uvolnit znova co je samozrejme blbost, ptz je v tom maglajz ze co je pointer a co je uz vytvoreny objekt (?). Len filozofujem ale moze to byt prave jeho problem.

Pointery se normalne v objektu nepouzivaji, protoze neni duvod.
To neco1 je staticke - treba metoda objektu, to neco2 je jen odkaz na objekt.
Neco1 muze byt i odkaz na jiny objekt

Realny priklad:

TMujObjekt = Class
private
  FObrazek: TImage;
public
  promennaCislo: Integer;
  promennaObrazek: TImage;
  property Obrazek: TImage read FObrazek write FObrazek;
end;

Read a write mohou byt i metody, ve kterych budes delat i neco jineho nez prirazeni do vnitrni promenne.
At provedes nekde prirazeni

MujObjekt.PromennaObrazek := Form1.Image1;
MujObjekt.Obrazek := Form1.Image2;

Pri ruseni objektu se ti prirazeny objekt sam nerusi, pokud to neudelas ty sam vedome kodem v destruktoru objektu. A je jedno, jestli si ho priradis takto nebo jako parametr v metode Create objektu. Predane objekty odkazem se samy nerusi.

Presne o tom pisem ze z toho tvojho zapisu neni jasne ci je v pamati cely objekt alebo ne.
promennaObrazek: TImage;
v pamati je teda alokovane co?

MujObjekt.PromennaObrazek := Form1.Image1;
v pamati je teda teraz alokovane co?

Ked zrusim Form1.Image1 tak ostane v pamati PromennaObrazek alokovane co?

V Delphi to programator nevidi = bordel. V C to jasne vidis ze co je fyzicky vytvorene v pamati. Bud pointer alebo objekt.

Oba zapisu jsou totozne a odkazuji se na objekt Form1.Imagex (je to jen forma pointeru). Nealokujes zadnou "kopii" objektu
Pokud zrusis Form1.Image1, tak v obou pripadech zustane v promenne i property odkaz na puvodni obrazek - bude odkazovat na neexistujici objekt.

V Delphi muzu udelat:

promennaObrazek := TImage.Create();  // vytvorim novy obrazek a do promenne priradim odkaz na nej
promennaObrazek := Form1.Image;       // do promenne priradim odkaz na existujici obrazek

Pokud to udelam takto, v te chvili jsem ztratil moznost se dostat k objektu, ktery jsem v prvnim radku vytvoril. Ale podobne dopadnu i v C, pokud dam new obrazek a pak to prepisu odkazem na nejaky existujici objekt. A pokud ten objekt z vnejsku zrusim, tak i C ti bude ukazovat na neexsitujici objekt.

Zpět do poradny Odpovědět na původní otázku Nahoru