Zwalnianie pamięci

0

Witam!
Mam taki problem z którym się męcze już dwa tygodnie i ciągle to samo. Jak poprawnie zwolnić pamięć. Banał.
Mam strukturę

struct M
{
  // ...
  char *d;
  char *f;
  // ...
}

Teraz wczytując z pliku sturktura po strukturze zajmuje pamiec dla wszystkiego co potrzebuje:

M = new[xxx];
d = new[xxx];
f = new[xxx];

Oczywiście M, d, f to wskaźniki do odpowiednich typów.
Następnie robię

List->Add(M);

Teraz mogę robić wszystko na tym i nic nie powoduje problemów. Dopiero jak próbuje zwolnić pamięć wywala mi naruszenie prawa dostępu. Uwalnianie wygląda mniej więcej tak:

for(int i = 0; i < List->Count - 1; i++){
  M *m;
  m = static_cast<struct M*>(List->Items[i]);
  delete[] m->d;
  delete[] m->f;
  delete m;
};
delete List;

Co jest z tym nie tak?

0

Dlaczego piszesz

   delete[] m->d;
   delete[] m->f;

a nie tak:

  delete m->d;
  delete m->f
0

Ponieważ

m->d i m->f

są wskaźnikami na tablicę char-ów, a tablice usówa się właśnie poprzez delete[].

0

Po pierwsze nie upierałbym sie przy delete[]. Po drugie skoro uzywasz metody (*list).Add(newitem) to chyba logiczne jest równiez użycie metody, która usuwa element z listy (może (*list).Remove(item), może inaczej).

Jeszcze ...

for(int i = 0; i < List->Count; i++)
0

Sprawdziłem zarówno delete jak i delete[]. Przy usuwaniu elementów z listy wypróbowałem zarówno Delete i Remove. Cały czas jednak dostaje EAccessViolation i pamięc zajęta dla M->d oraz M->f nigdy nie zostaje zwalniana (tak twierdzi CodeGourd).
Zastanawiałem się czy nie dobieram się do cudzej pamięci albo do NULL-a. Tylko, że mogę odczytać to co jest pod M->d i M->f, więc pamięc jest poprawnie zaalokowana. Wszelkie operacje typu strcpy() czy inne działają, więc tu nie powinno być problemu. A skoro pamięć jest zajęta poprawnie nie ma możliwości żeby się dobierał do nie swojej pamięci chyba.
Czy to robi jakąś różnicę, że kod zajmujący i zwalniający pamięć jest w dll-ce?

0

Zapodaj dokladny kod tworzenia tej struktury, przydzielania pamieci dla niej i wypelniania jej.

0
M *m = new M;
m->d = new char[xxx];
m->f = new char[yyy];

Wszystko oczywiście jakoś poukładane w bloki try catch.
Wypełniam to co się tam znajduje poprzez strcpy(m->d, Memo1->Text.c_str());
Ilość pamięci zajmowanej na m->d i m->f obliczam Memo1->Text.Length()+1;
Chyba prościej się nie da tego zrobić. Potrzebuje te dwa wskaźniki na char bo nigdy nie wiem ile będe musiał umieścić tam tekstu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1