• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Czy powinienem zastosować new i delete?

0 głosów
116 wizyt
pytanie zadane 9 lutego w C i C++ przez jankustosz1 Pasjonat (16,550 p.)

Zobaczyłem posta o podobnej tematyce to sobie przypomniałem problem jaki miałem.

Jak mam taką strukturę:

struct Node
{
 Node *l = nullptr, *r = nullptr;
 void jakasmetoda()
 {
  l=new Node();
  r= new Node();
 }

}

To mam do tego kilka pytań. Czy dałoby się jakoś nie stosować new? Np. zrobić coś tego typu:

l = &Node()

Kolejne pytanie czy jeżeli już musiałbym korzystać z new. To czy jakbym na OI czy jakiejkolwiek innej sprawdzaczce wysłał zadanie gdzie nie zwalniałbym bo sobie pamięci byłby to problem? Każdy test jest uruchamiany w nowym środowisku czy może np. pamięć wywalić?

2 odpowiedzi

0 głosów
odpowiedź 9 lutego przez Arkadiusz Sikorski Pasjonat (17,880 p.)

Niech mnie ktoś poprawi w razie czego, ale

To mam do tego kilka pytań. Czy dałoby się jakoś nie stosować new? Np. zrobić coś tego typu:

l = &Node()

W takim kodzie tworzysz obiekt Node na stosie i przypisujesz do wskaźnika adres zmiennej na stosie. Po zakończeniu działania danej funkcji obiekt o adresie przypisanym do tego wskaźnika nie istniałby i najprawdopodobniej skończyłoby się to błędem naruszenia pamięci. Zadbaj o odpowiednie destruktory, które posprzątają i zdealokują pamięć.

gdzie nie zwalniałbym bo sobie pamięci

A dlaczego nie chciałbyś jej zwalniać?  

komentarz 10 lutego przez jankustosz1 Pasjonat (16,550 p.)

Nie chciałbym zwalniać bo to strata czasu, a na OI każda minuta jest ważna, do tego po co robić coś co może być niepotrzebne i tylko spowalnia program.

To wytłumacz mi inną rzecz, dlaczego ten Kod jest poprawny:

struct A
{
 int x, y, z;
}

int main()
{
  vector<A> t;
  t.push_back(A()); /// nie muszę robić ani tablicy wskaźników, ani używać operatora new, a obiekt sam wie kiedy ma się zwolnić
}

 

1
komentarz 10 lutego przez Arkadiusz Sikorski Pasjonat (17,880 p.)

Nie chciałbym zwalniać bo to strata czasu

Dobrze rozumiem, że chcesz usprawnić swoje rozwiązanie poprzez niedealokowanie dynamicznych zmiennych? Pomysł jest moim zdaniem bzdurny.

po co robić coś co może być niepotrzebne i tylko spowalnia program

Tego typu konkursy mają najczęściej limity pamięci. Jeśli Twoje rozwiązanie przekroczy limit pamięci, to co wtedy? Już nie mówiąc o tym, że to "niezgodne ze sztuką". Lepiej zadbaj o odpowiednie struktury danych - na przykład takie z nadmiarową alokacją (tak na przykład działa std::vector - jeśli brakuje miejsca, to alokuje nowy blok np. dwa razy większy niż stary, a nie większy o wielkość jednego elementu). Drugą kluczową sprawą jest oczywiście sam algorytm.

 

Tak swoją drogą, w powyższym kodzie nadal występuje alokacja - jeśli nie ma miejsca w wektorze, to push_back powoduje alokację (a dokładnie alokację nowego, większego bloku, przepisanie starych wartości do nowego bloku i dealokację starego bloku).

komentarz 10 lutego przez jankustosz1 Pasjonat (16,550 p.)

Nie chciałbym zwalniać bo to strata czasu

Chodziło mi o stratę czasu na pisanie zwalniania pamięci, bo jeżeli nie jest to konieczne to nie warto pisać, to że szybciej będzie działał program to tylko poboczna korzyść.

Jeżelibym musiał robić delete bo przekroczyłoby limit pamięci to oczywiście bym to robił, ale chodzi mi o przypadki, gdy wystarcza pamięci, i pytanie jest czy jak na koniec nie wyczyszczę pamięci, to czy sprawdzarka odpali wszystko w wirtualnej maszynie od nowa, czy nie wyczyści pamięci i tamto poprzednie będzie dalej jako zajęte. Wydaje mi się że chyba nie powinna działać w ten drugi sposób, bo jak np. w jakimś teście się program wywala i nieczyści pamięci, a w kolejnych przykładach tak nie robi, to kolejne powinny być uznane a tylko ten jeden nie.

Odnośnie tego kodu. To nie jest tak, że najpierw jest tworzony ten obiekt i wrzucany jest do metody w wektorze, a po zakończeniu linii obiekt jest czyszczony, tak samo jak w tym pierwszym przykładzie? 

komentarz 10 lutego przez Criss Mędrzec (161,360 p.)

@Arkadiusz Sikorski,

W takim kodzie tworzysz obiekt Node na stosie i przypisujesz do wskaźnika adres zmiennej na stosie.

Przede wszystkim - Node() to rvalue, a adresu rvalue nie da się pobrać bo tak (tj. standard tak mówi).

 @jankustosz1,

To wytłumacz mi inną rzecz, dlaczego ten Kod jest poprawny: (...)

Po pierwsze - obiekt nie "sam wie kiedy ma się zwolnić", tylko robi to vector. A co do pytania: działa, bo vectorze ląduje nie obiekt który dajesz do push_back, tylko jego kopia. A() jest rvalue i istnieje "do najbliższego średnika".

Chodziło mi o stratę czasu na pisanie zwalniania pamięci,

Serio. Jak wolno piszesz 

komentarz 10 lutego przez jankustosz1 Pasjonat (16,550 p.)
Rzeczywiście ląduje kopia, to wszystko wyjaśnia.

A jeżelibym nie chciał żeby lądowała kopia musiałbym zrobić wektor wskaźników? Jakby wektor zawierał referencje to i tak to nic nie zmieni, bo jak prześlę zmienną w push_backu to i tak się zrobi jej kopia. Btw. po co push_back pobiera adres zmiennej skoro i tak z niego nie korzysta i robi kopię?
0 głosów
odpowiedź 10 lutego przez Criss Mędrzec (161,360 p.)

Czy dałoby się jakoś nie stosować new?

Wskaźnik może wskazywać na co chcesz nieważne jak zostało zaalokowane. Ale fajnie by jednak było gdyby nigdy nie zdarzyło się tak, że wskaźnik wskazuje na już nieistniejący obiekt...

czy jeżeli już musiałbym korzystać z new. To czy jakbym na OI czy jakiejkolwiek innej sprawdzaczce wysłał zadanie gdzie nie zwalniałbym bo sobie pamięci byłby to problem?

Jeśli "sprawdzarka" patrzy czy robisz memleaki - no to tak, to jest problem. Jeśli nie... no to byle nie przekroczyć limitu pamięci. Aczkolwiek nie wiem dlaczego miałbyś nie zwalniać pamięci... 

komentarz 10 lutego przez jankustosz1 Pasjonat (16,550 p.)
W zasadzie streściłeś moje pytanie. Tylko pytanie jest czy sprawdzaczki, patrzą na memleaki. Potestuję to napiszę, jak z tym jest.

Podobne pytania

0 głosów
1 odpowiedź 269 wizyt
0 głosów
2 odpowiedzi 90 wizyt
pytanie zadane 21 lutego 2018 w C i C++ przez Mihost Nowicjusz (240 p.)
0 głosów
0 odpowiedzi 164 wizyt
pytanie zadane 22 maja 2016 w C i C++ przez L33TT12 Gaduła (3,960 p.)
Porady nie od parady
Zadając pytanie postaraj się o poprawną pisownię i czytelne formatowanie tekstu.Kompozycja

60,245 zapytań

105,929 odpowiedzi

220,065 komentarzy

32,445 pasjonatów

Przeglądających: 187
Pasjonatów: 5 Gości: 182

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...