Jak usuwać dynamiczne obiekty z pamięci?

dział ogólny

Jak usuwać dynamiczne obiekty z pamięci?

Nowy postprzez kurczez » środa, 20 stycznia 2010, 09:29

Jak usuwać dynamiczne obiekty po zakończeniu pracy z nimi?
Ja to robię w ten sposób, że w zdarzeniu OnClose głównej formy zwalniam w pętli wszystkie obiekty z tabeli:

Kod: Zaznacz cały
for (unsigned int i = 0; i <= dnie; i++) {
   dnM[i]->Free();
}


Niezależnie od tego czy zastosuje ten kod czy nie to i tak podczas zamykania programu wyskakuje błąd.
Avatar użytkownika
kurczez
Homos antropiczny
Homos antropiczny
 
Posty: 56
Dołączył(a): sobota, 10 października 2009, 18:58
Podziękował : 4
Otrzymał podziękowań: 0
System operacyjny: Vista
Kompilator: Turbo C++
Gadu Gadu: 0
    Windows VistaFirefox

Re: Jak usuwać dynamiczne obiekty z pamięci?

Nowy postprzez Cyfrowy Baron » środa, 20 stycznia 2010, 10:09

Błąd wyskakuje pewnie dlatego, że uwalniasz więcej obiektów niż ich utworzyłeś. Wszystkie obiektu kasowane w pętli muszą istnieć. Być może powinieneś zmienić zakres działania pętli z i <= dnie, na i < dnie.

W C++ zaleca się używanie delete zamiast funkcji Free():

Help C++Builder 2007:
► 


Kod: Zaznacz cały
for(unsigned int i = 0; i <= dnie; i++)
{
  delete dnM[i];
}
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4719
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Jak usuwać dynamiczne obiekty z pamięci?

Nowy postprzez kurczez » środa, 20 stycznia 2010, 10:40

Zmieniłem na delete i zmniejszyłem pętlę o 1 wywołanie, ale problemu to nie rozwiązało.

Podczas zamykania wyskakuje błąd:


---------------------------
Debugger Exception Notification
---------------------------
Project test.exe raised exception class EInvalidPointer with message 'Invalid pointer operation'.
---------------------------
Break Continue Help
---------------------------



Program wywala się na tej linii:

Kod: Zaznacz cały
procedure TObject.FreeInstance;
begin
  CleanupInstance;
  _FreeMem(Self); // na tej, jest to plik system
end;


Tak jak pisałem w pierwszym poście jeżeli sam nic nie usuwam to i tak wyskakuje ten błąd, więc raczej jego przyczyną nie jest to, że próbuje zwolnić obiekt, którego nie ma.
Avatar użytkownika
kurczez
Homos antropiczny
Homos antropiczny
 
Posty: 56
Dołączył(a): sobota, 10 października 2009, 18:58
Podziękował : 4
Otrzymał podziękowań: 0
System operacyjny: Vista
Kompilator: Turbo C++
Gadu Gadu: 0
    Windows VistaFirefox

Re: Jak usuwać dynamiczne obiekty z pamięci?

Nowy postprzez Cyfrowy Baron » środa, 20 stycznia 2010, 10:47

Tak jak pisałem w pierwszym poście jeżeli sam nic nie usuwam to i tak wyskakuje ten błąd,


Nie rozumiem tej wypowiedzi. Czyli jeżeli nic nie usuwasz, czyli w trakcie działania programu jest bład?! Co to właściwie znaczy?
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4719
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Jak usuwać dynamiczne obiekty z pamięci?

Nowy postprzez kurczez » środa, 20 stycznia 2010, 10:57

W zdarzeniu OnClose formy wykonuje taki kod:

Kod: Zaznacz cały
for (unsigned int i = 0; i < dnie; i++) {
   delete dnM[i];
}


Czy go wykonam czy nie to nie robi to różnicy. Podczas zamykania programu wyskakuje ten sam błąd. Także kod, którego używam nie powoduje błędu.
Avatar użytkownika
kurczez
Homos antropiczny
Homos antropiczny
 
Posty: 56
Dołączył(a): sobota, 10 października 2009, 18:58
Podziękował : 4
Otrzymał podziękowań: 0
System operacyjny: Vista
Kompilator: Turbo C++
Gadu Gadu: 0
    Windows VistaFirefox

Re: Jak usuwać dynamiczne obiekty z pamięci?

Nowy postprzez Cyfrowy Baron » środa, 20 stycznia 2010, 11:02

Więc błąd ma związek z biblioteką, albo z tym jak tworzysz te obiekty dynamicznie.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4719
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Jak usuwać dynamiczne obiekty z pamięci?

Nowy postprzez kurczez » środa, 20 stycznia 2010, 11:32

Tworzę je tak:

Kod: Zaznacz cały
dnM[dnie] = new TScintilla(TabControl2);
Avatar użytkownika
kurczez
Homos antropiczny
Homos antropiczny
 
Posty: 56
Dołączył(a): sobota, 10 października 2009, 18:58
Podziękował : 4
Otrzymał podziękowań: 0
System operacyjny: Vista
Kompilator: Turbo C++
Gadu Gadu: 0
    Windows VistaFirefox

Re: Jak usuwać dynamiczne obiekty z pamięci?

Nowy postprzez Cyfrowy Baron » środa, 20 stycznia 2010, 11:40

Tyle to chyba za mało, a gdzie przypisujesz "rodzica"?

Kod: Zaznacz cały
dnM[dnie] = new TScintilla(TabControl2);
dbN[dnie]->Parent = this;


Poza tym, czy dnie nie ma przypadkiem stałej wartość określającej maksymalna liczbę obiektów? Bo jeżeli tak to nie tworzysz wielu obiektów lecz jeden o o numerze dnie. Nie można utworzyć wielu obiektów podając tylko ich maksymalna liczbę:

Kod: Zaznacz cały
for(int i = 0; i < dnie; i++)
{
dnM[i] = new TScintilla(TabControl2);
dbN[i]->Parent = this;
}
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4719
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Jak usuwać dynamiczne obiekty z pamięci?

Nowy postprzez kurczez » środa, 20 stycznia 2010, 11:55

Kod: Zaznacz cały
dnM[dnie] = new TScintilla(TabControl2);
   dnM[dnie]->Parent = TabControl2;


Rodzicem musi być obiekt TabControl2 ponieważ kontrolka ma się na nim tworzyć.

dnie to zmienna, której wartość jest inkrementowana wraz z przybywaniem nowych obiektów typu TScintilla.

Kod: Zaznacz cały
dnM[dnie] = new TScintilla(TabControl2);
dnM[dnie]->Parent = TabControl2;
...
dnie++;
Avatar użytkownika
kurczez
Homos antropiczny
Homos antropiczny
 
Posty: 56
Dołączył(a): sobota, 10 października 2009, 18:58
Podziękował : 4
Otrzymał podziękowań: 0
System operacyjny: Vista
Kompilator: Turbo C++
Gadu Gadu: 0
    Windows VistaFirefox

Re: Jak usuwać dynamiczne obiekty z pamięci?

Nowy postprzez Cyfrowy Baron » środa, 20 stycznia 2010, 11:56

Za mało danych do odnalezienia przyczyny błędu.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4719
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Jak usuwać dynamiczne obiekty z pamięci?

Nowy postprzez kurczez » środa, 20 stycznia 2010, 12:10

Tak wygląda u mnie cały kod odpowiedzialny za dynamiczne stworzenie tej kontrolki:

Kod: Zaznacz cały
if (OpenDialog1->Execute()) {

   TabControl2->Tabs->Add(ExtractFileName(OpenDialog1->FileName));

   dnM[dnie] = new TScintilla(TabControl2);
   dnM[dnie]->Parent = TabControl2;
   dnM[dnie]->OnKeyPress = dnM1OnKeyPress; // podczepiam procedure OnKeyPress
   dnM[dnie]->OnModified = dnM1Modified; // podczepiam procedure OnModified
   dnM[dnie]->KeyCommands = Memo1->KeyCommands; // Memo1 to oczywiście obiekt typu TScintilla
   dnM[dnie]->LanguageManager = Memo1->LanguageManager;
   dnM[dnie]->Font = Memo1->Font;
   dnM[dnie]->Colors = Memo1->Colors;
   dnM[dnie]->WordWrap = Memo1->WordWrap;
   dnM[dnie]->Align = Memo1->Align;
   dnM[dnie]->BorderStyle = Memo1->BorderStyle;
   dnM[dnie]->EdgeColumn = Memo1->EdgeColumn;
   dnM[dnie]->Indentation = Memo1->Indentation;
   Memo10->Lines->LoadFromFile(OpenDialog1->FileName);
   //dnM[dnie]->Lines->Text = Memo10->Text;
   dnM[dnie]->Visible = true;
   dnM[dnie]->Show();
   wez = dnie; // inicjalizuje wez wartoscia dnie abym mogl w watku nSt odniesc sie do utworzonego obiektu w celu przypisaniu mu focusu.

   CreateThread( NULL, 0, nSt, 0, 0, &threadID); // w tym wątku chce ustawić bezskutecznie focus na dnM[dnie]

   dnie++;

   TabControl2->TabIndex = dnie;

   SLH(OpenDialog1->FileName, ExtractFileName(OpenDialog1->FileName)); // tutaj sobie coś czytam i zapisuje do bazy danych
}


Potrzebujesz jeszcze jakiś danych?
Avatar użytkownika
kurczez
Homos antropiczny
Homos antropiczny
 
Posty: 56
Dołączył(a): sobota, 10 października 2009, 18:58
Podziękował : 4
Otrzymał podziękowań: 0
System operacyjny: Vista
Kompilator: Turbo C++
Gadu Gadu: 0
    Windows VistaFirefox

Re: Jak usuwać dynamiczne obiekty z pamięci?

Nowy postprzez Cyfrowy Baron » środa, 20 stycznia 2010, 12:23

Po pierwsze to czego nie zauważyłem od razu to nie:


Kod: Zaznacz cały
dnM[dnie] = new TScintilla(TabControl2);
dnM[dnie]->Parent = TabControl2;

lecz:

Kod: Zaznacz cały
dnM[dnie] = new TScintilla(this);
dnM[dnie]->Parent = TabControl2;


Właścicielem jest okno programu. TabControl2 jest rodzicem.



Pokaż jeszcze deklarację obiektu w pliku nagłówkowym.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4719
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Jak usuwać dynamiczne obiekty z pamięci?

Nowy postprzez kurczez » środa, 20 stycznia 2010, 12:35

Właścicielem jest okno programu. TabControl2 jest rodzicem.


Tak miałem na początku i jak nie działało to zmieniłem na TabControl2.

Pokaż jeszcze deklarację obiektu w pliku nagłówkowym.


Nie rozumiem pytania, chodzi o to?

Kod: Zaznacz cały
TScintilla *dnM[128] = {0};


Mam to zadeklarowane w pliku .cpp
Avatar użytkownika
kurczez
Homos antropiczny
Homos antropiczny
 
Posty: 56
Dołączył(a): sobota, 10 października 2009, 18:58
Podziękował : 4
Otrzymał podziękowań: 0
System operacyjny: Vista
Kompilator: Turbo C++
Gadu Gadu: 0
    Windows VistaFirefox

Re: Jak usuwać dynamiczne obiekty z pamięci?

Nowy postprzez Cyfrowy Baron » środa, 20 stycznia 2010, 12:41

Tak miałem na początku i jak nie działało to zmieniłem na TabControl2.


Powinno działać, a próbowałeś:

Kod: Zaznacz cały
dnM[dnie] = new TScintilla(this->Handle);
dnM[dnie]->Parent = TabControl2;




A nie wystarczyło tak:

Kod: Zaznacz cały
private:
        TScintilla *dnM[128];




Po co to: dnM[dnie]->Show();



Kod: Zaznacz cały
   Memo10->Lines->LoadFromFile(OpenDialog1->FileName);
   //dnM[dnie]->Lines->Text = Memo10->Text;


Po co ładujesz najpierw do Memo10 a potem źle to przepisujesz do dniM, jeżeli już to powinno być tak:

Kod: Zaznacz cały
   Memo10->Lines->LoadFromFile(OpenDialog1->FileName);
   //dnM[dnie]->Text = Memo10->Text;




Gdy tak patrzę na ten Twój kod to wydaje mi się, że błąd wywołują tutaj wątki, a nie Scintilla.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4719
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Jak usuwać dynamiczne obiekty z pamięci?

Nowy postprzez kurczez » środa, 20 stycznia 2010, 13:00

A nie wystarczyło tak:


Jak tak zrobiłem to kompilator nie mógł znaleźć dnM, może zamieścić to w sekcji public?

Kod: Zaznacz cały
[C++ Error] Unit2.cpp(1850): E2451 Undefined symbol 'dnM'


Po co to: dnM[dnie]->Show();


Wcześniej to działało na kontrolkach klasy TMemo i one po utworzeniu są schowane lub niewidoczne, dlatego użyłem visible = true i Show(). Jeśli TScintilla normalnie się pokazuje to wykasuje to.

Po co ładujesz najpierw do Memo10 a potem źle to przepisujesz do dniM, jeżeli już to powinno być tak:


To jest poprawne przypisanie, inaczej tego zrobić nie można. Obiekty klasy TScintilla nie mają metody Text, można się do niej dostać tylko za pomocą Lines->Text. Podczas próby wczytania pliku przez LoadFromFile TScintilla powoduje błąd. Dlatego najpierw wczytuje do Memo10 a następnie przenoszę do dnM[dnie].

Gdy tak patrzę na ten Twój kod to wydaje mi się, że błąd wywołują tutaj wątki, a nie Scintilla.


W wątku to ja tylko próbuje ustawić focus okna, bez tego wątku na 99,9% problem i tak wystąpi.
Avatar użytkownika
kurczez
Homos antropiczny
Homos antropiczny
 
Posty: 56
Dołączył(a): sobota, 10 października 2009, 18:58
Podziękował : 4
Otrzymał podziękowań: 0
System operacyjny: Vista
Kompilator: Turbo C++
Gadu Gadu: 0
    Windows VistaFirefox

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 5 gości

cron