• 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?

VPS Starter Arubacloud
0 głosów
236 wizyt
pytanie zadane 9 lutego 2019 w C i C++ przez jankustosz1 Nałogowiec (35,880 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 2019 przez Arkadiusz Sikorski Pasjonat (20,160 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 2019 przez jankustosz1 Nałogowiec (35,880 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 2019 przez Arkadiusz Sikorski Pasjonat (20,160 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 2019 przez jankustosz1 Nałogowiec (35,880 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 2019 przez criss Mędrzec (172,590 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 2019 przez jankustosz1 Nałogowiec (35,880 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 2019 przez criss Mędrzec (172,590 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 2019 przez jankustosz1 Nałogowiec (35,880 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ź 617 wizyt
0 głosów
1 odpowiedź 142 wizyt
pytanie zadane 30 marca 2020 w C i C++ przez Quegon23 Nowicjusz (150 p.)
0 głosów
1 odpowiedź 605 wizyt
pytanie zadane 4 października 2020 w C i C++ przez sebaaas Początkujący (350 p.)

92,455 zapytań

141,263 odpowiedzi

319,099 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...